﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using log4net;
using System.Threading;
using System.Collections.Concurrent;
using HalconDotNet;
using System.Net;
using Cognex.DataMan.SDK;
using Cognex.DataMan.SDK.Utils;
using System.Data.SqlClient;
using System.Xml;

namespace AssemblyCYG
{
    public partial class MainForm : Form
    {
        #region 全局变量
        HalconDotNet.HSmartWindowControl hWindowControl_glue = new HSmartWindowControl();
        HalconDotNet.HSmartWindowControl hWindowControl_guide = new HSmartWindowControl();
        HalconDotNet.HSmartWindowControl hWindow_upCam = new HSmartWindowControl();
        HalconDotNet.HSmartWindowControl hWindow_downCam = new HSmartWindowControl();
        HalconDotNet.HSmartWindowControl hWindow_scanCode = new HSmartWindowControl();
        HalconDotNet.HSmartWindowControl hWindow_siMo = new HSmartWindowControl();
        HalconDotNet.HSmartWindowControl hWindow_reviewEx3 = new HSmartWindowControl();    //halcon显示图像控件

        HalconAlgorithm halconAlgorithm = new HalconAlgorithm();
        ConcurrentQueue<HObject> downCamQueue = new ConcurrentQueue<HObject>();       //下相机
        ConcurrentQueue<HObject> upCamQueue = new ConcurrentQueue<HObject>();         //上相机
        ConcurrentQueue<HObject> CodedownCamQueue = new ConcurrentQueue<HObject>();         //上相机扫码
        ConcurrentQueue<HObject> detectCamQueue = new ConcurrentQueue<HObject>();     //自检或胶形检测相机
        ConcurrentQueue<saveImageInfo> saveQueue = new ConcurrentQueue<saveImageInfo>();     //保存图像队列
        ConcurrentQueue<int> channelQueue = new ConcurrentQueue<int>();              //流道排序
        System.Diagnostics.Stopwatch detectTime = new System.Diagnostics.Stopwatch();
        private delegate void DGSetStateShow(string state, Color frontColor);
        DGSetStateShow dGSetStateShow = null;
        public string StartTime = "";         //当前开始时间
        public string EndTime = "";           //当前结束时间
        public string DMConnectStatus = "";   //条码枪连接状态
        CINIFactory cIniFactory = null;       //统计产量
        Thread requestPhotoThread = null;
        Thread proDownCamThread = null;
        Thread proUpCamThread = null;
        Thread proViewCamThread = null;
        Thread SaveImageThread = null;                                             //保存图像线程        
        bool threadBusy = false;
        bool downCamLocatDown = false;
        bool downCamCodeDown = false;
        bool downCamSiMoDown = false;
        bool upCamLocatDown1 = false;
        bool upCamLocatDown2 = false;
        bool bDownNG = false;
        public string strCode = "";
        ILog logTrace = null;
        ILog logError = null;
        int proTotalNum = 0;
        int proOkNum = 0;
        double proOkRatio = 0;
        CLogFactory logRecord;
        HTuple hv_HomMat2DCoilReview2;
        public enum WorkStatus
        {
            等待,
            下相机组装,
            上相机组装1,
            上相机组装2,
            下相机XY补偿,
            复检_曝光1,
            复检_曝光2,
            复检_曝光3,
            胶形检测,
            机械手引导,
            撕膜工位,
            扫码
        }
        WorkStatus detectCamStatus { get; set; }   //每个相机处于一个状态
        WorkStatus downCamStatus { get; set; }
        WorkStatus upCamStatus { get; set; }
        HTuple hv_downCamModel = null;   //下相机模板
        HTuple hv_upCamModel = null;     //上相机模板
        HTuple hv_reviewModel = null;   //Coil复检1模板
        HTuple hv_coilreview1Model = null;
        bool isLoadDownCamModel = false;   //判断是否加载模板成功
        bool isLoadUpCamModel = false;
        bool isLoadReviewModel = false;
        bool isLoadReview1Model = false;
        double downCamPos_X { get; set; }    //当前下相机像素位置
        double downCamPos_Y { get; set; }
        double downCamPos_Phi { get; set; }  //匹配到的模板与标准模板的角度
        double upCamPos1_X { get; set; }      //当前上相机像素位置
        double upCamPos1_Y { get; set; }
        double upCamPos1_Phi { get; set; }
        double upCamPos2_X { get; set; }      //当前上相机像素位置
        double upCamPos2_Y { get; set; }
        double upCamPos2_Phi { get; set; }
        double offset_X { get; set; }       //x方向偏差，世界坐标
        double offset_Y { get; set; }
        double offset_Phi { get; set; }
        //double offset_firstPhi { get; set; }

        HObject reviewLowImage = null;            //复检低曝光图像
        HObject downCamImage = null;              //下相机图像
        HObject codeImage = null;              //下相机Code图像
        bool isEnableLink { get; set; }         //是否启用Link
        //扫码枪
        private SynchronizationContext _syncContext = null;
        public ResultCollector _results; /*= new ResultCollector();*/
        public static ISystemConnector _connector = null;
        public DataManSystem _system = null;
        public object _currentResultInfoSyncLock = new object();
        public ComplexResult mComplexResult = new ComplexResult();
        public Image CodeImage;
        string SNCode = "";
        string SpringCode = "";
        string configCode = "";
        string saveFileName = "";

        HObject upCamROI_circle = null;
        HObject upCamROI_line1 = null;
        HObject upCamROI_line2 = null;

        public HObject ho_UpCam1 = null;
        public HObject ho_UpCam2 = null;
        public HObject ho_DownCam = null;
        public HObject ho_CodeCam = null;

        HObject upCamROI2_circle = null;
        HObject upCamROI2_line1 = null;
        HObject upCamROI2_line2 = null;

        HObject downCamROI_circle = null;
        HObject downCamROI_line1 = null;
        HObject downCamROI_line2 = null;
        HObject review1ROI_circle = null;  //puck
        HObject review1ROI_line1 = null;   //针对puck
        HObject review1ROI_line2 = null;
        HObject review1ROI_line3 = null;   //针对spring
        HObject review1ROI_line4 = null;
        HObject review2ROI_line1 = null;
        HObject review2ROI_line2 = null;
        HObject review2ROI_circle = null;   //sping 
        HObject review3ROI_line1 = null;
        HObject review3ROI_line2 = null;
        int angleRegulateNum = 0;    //下相机角度校正的次数
        bool isEmptyRun = false;      //是否执行空跑
        bool angleRotateOK = false;
        private static object lockSignal = new object();
        HTuple downCamHomMat2D = null;
        HTuple upCam1HomMat2D = null;
        HTuple upCam2HomMat2D = null;
        #endregion
        public MainForm()
        {
            InitializeComponent();
            LoadCalPara();

            ShareData.downCamPixSize = 0.015154;
            ShareData.upCamPixSize1 = 0.01885227;
            ShareData.upCamPixSize2 = 0.01885227;

            hWindowControl_guide.MouseWheel += HWindowControl_guide_MouseWheel;
            hWindow_upCam.MouseWheel += HWindow_upCam_MouseWheel;
            hWindow_downCam.MouseWheel += HWindow_downCam_MouseWheel;
            hWindow_siMo.MouseWheel += HWindow_siMo_MouseWheel;
            hWindow_scanCode.MouseWheel += HWindow_scanCode_MouseWheel;

            ShareData.MvsCameral.captureImage += MvsCameral_captureImage;              //绑定采集图像事件
            // receiveInfoAutoHandler += tcpClient_receiveInfoAutoHandler;
            this.dGSetStateShow = new DGSetStateShow(SetStateShow);
            ShareData.MvsCameral.HKImageCallBack();                                    //启用相机回掉函数
            ProjectInfo.ReadProjectConfig(ShareData.configPath);   //创建配置文件

            halconAlgorithm.innerRadius = ProjectInfo.Parameter.innerRadius;
            halconAlgorithm.outerRadius = ProjectInfo.Parameter.outerRadius;

            this.lab_VersionID.Text = "Version：" + Application.ProductVersion.ToString();   //版本号
            //log4net.Config.XmlConfigurator.Configure();           //创建Log文件
            //logTrace = log4net.LogManager.GetLogger("loginfo");   //获取一个日志记录器
            //logError = log4net.LogManager.GetLogger("logerror");
            //this.logTrace.Info(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss fff") + "打开软件！");
            InitialProStatis();                                   //加载统计数据
            InitialHalconControls();
            //InitialCognexScanner();                               //加载扫码枪
            操作员ToolStripMenuItem_Click(null, null);   //默认进入操作员模式
            InitialProjectType();
            //JudgeFileKeepDays();                   //判断文件存留期限
            logRecord = new CLogFactory("\\Log\\", "Log");
            logRecord.WriteLog("打开软件");
            CheckForIllegalCrossThreadCalls = false;
            HObject ho_image = null;
            HOperatorSet.GenEmptyObj(out ho_image);
            HOperatorSet.ReadImage(out ho_image, System.Environment.CurrentDirectory + "\\region\\image.bmp");
            ho_image.Dispose();
        }

        #region 图像窗口缩放

        private void HWindowControl_guide_MouseWheel(object sender, MouseEventArgs e)
        {
            Point pt = hWindowControl_guide.Location;
            int leftBorder = hWindowControl_guide.Location.X;
            int rightBorder = hWindowControl_guide.Location.X + hWindowControl_guide.Size.Width;
            int topBorder = hWindowControl_guide.Location.Y;
            int bottomBorder = hWindowControl_guide.Location.Y + hWindowControl_guide.Size.Height;

            if (e.X > leftBorder && e.X < rightBorder && e.Y > topBorder && e.Y < bottomBorder)
            {
                MouseEventArgs newe = new MouseEventArgs(e.Button, e.Clicks, e.X - pt.X, e.Y - pt.Y, e.Delta);
                hWindowControl_guide.HSmartWindowControl_MouseWheel(sender, newe);
            }
        }

        private void HWindow_upCam_MouseWheel(object sender, MouseEventArgs e)
        {
            Point pt = hWindow_upCam.Location;
            int leftBorder = hWindow_upCam.Location.X;
            int rightBorder = hWindow_upCam.Location.X + hWindow_upCam.Size.Width;
            int topBorder = hWindow_upCam.Location.Y;
            int bottomBorder = hWindow_upCam.Location.Y + hWindow_upCam.Size.Height;

            if (e.X > leftBorder && e.X < rightBorder && e.Y > topBorder && e.Y < bottomBorder)
            {
                MouseEventArgs newe = new MouseEventArgs(e.Button, e.Clicks, e.X - pt.X, e.Y - pt.Y, e.Delta);
                hWindow_upCam.HSmartWindowControl_MouseWheel(sender, newe);
            }
        }

        private void HWindow_downCam_MouseWheel(object sender, MouseEventArgs e)
        {
            Point pt = hWindow_downCam.Location;
            int leftBorder = hWindow_downCam.Location.X;
            int rightBorder = hWindow_downCam.Location.X + hWindow_downCam.Size.Width;
            int topBorder = hWindow_downCam.Location.Y;
            int bottomBorder = hWindow_downCam.Location.Y + hWindow_downCam.Size.Height;

            if (e.X > leftBorder && e.X < rightBorder && e.Y > topBorder && e.Y < bottomBorder)
            {
                MouseEventArgs newe = new MouseEventArgs(e.Button, e.Clicks, e.X - pt.X, e.Y - pt.Y, e.Delta);
                hWindow_downCam.HSmartWindowControl_MouseWheel(sender, newe);
            }
        }

        private void HWindow_siMo_MouseWheel(object sender, MouseEventArgs e)
        {
            Point pt = hWindow_siMo.Location;
            int leftBorder = hWindow_siMo.Location.X;
            int rightBorder = hWindow_siMo.Location.X + hWindow_siMo.Size.Width;
            int topBorder = hWindow_siMo.Location.Y;
            int bottomBorder = hWindow_siMo.Location.Y + hWindow_siMo.Size.Height;

            if (e.X > leftBorder && e.X < rightBorder && e.Y > topBorder && e.Y < bottomBorder)
            {
                MouseEventArgs newe = new MouseEventArgs(e.Button, e.Clicks, e.X - pt.X, e.Y - pt.Y, e.Delta);
                hWindow_siMo.HSmartWindowControl_MouseWheel(sender, newe);
            }
        }
        private void HWindow_scanCode_MouseWheel(object sender, MouseEventArgs e)
        {
            Point pt = hWindow_scanCode.Location;
            int leftBorder = hWindow_scanCode.Location.X;
            int rightBorder = hWindow_scanCode.Location.X + hWindow_scanCode.Size.Width;
            int topBorder = hWindow_scanCode.Location.Y;
            int bottomBorder = hWindow_scanCode.Location.Y + hWindow_scanCode.Size.Height;

            if (e.X > leftBorder && e.X < rightBorder && e.Y > topBorder && e.Y < bottomBorder)
            {
                MouseEventArgs newe = new MouseEventArgs(e.Button, e.Clicks, e.X - pt.X, e.Y - pt.Y, e.Delta);
                hWindow_scanCode.HSmartWindowControl_MouseWheel(sender, newe);
            }
        }

        #endregion

        #region 初始化设置
        private void InitialProjectType()
        {
            try
            {
                CINIFactory projectType = new CINIFactory(System.Environment.CurrentDirectory + "\\", "item");    //加载统计数据
                int projectIndex = int.Parse(projectType.ReadIniData("item", "type", ""));
                ShareData.loginPassword = projectType.ReadIniData("password", "password", "");    //加载管理员登陆密码
                //this.groupBox8.Visible = false;
                switch (projectIndex)
                {
                    case 1:
                        ShareData.projectItem = ShareData.ItemType.自动线spring组装;
                        this.tab_leftShow.TabPages.Add("", "上相机定位", "");
                        this.tab_leftShow.TabPages.Add("", "机械手引导", "");
                        this.tab_rightShow.TabPages.Add("", "下相机定位", "");
                        this.tab_leftShow.TabPages[0].Controls.Add(this.hWindow_upCam);
                        this.hWindow_upCam.Dock = DockStyle.Fill;
                        this.tab_leftShow.TabPages[1].Controls.Add(this.hWindowControl_guide);
                        this.hWindowControl_guide.Dock = DockStyle.Fill;
                        this.tab_rightShow.TabPages[0].Controls.Add(this.hWindow_downCam);
                        this.hWindow_downCam.Dock = DockStyle.Fill;
                        this.lab_fixture.Text += "自动线Spring组装";
                        break;
                    case 2:
                        ShareData.projectItem = ShareData.ItemType.自动线coil组装;
                        this.tab_leftShow.TabPages.Add("", "上相机定位", "");
                        this.tab_leftShow.TabPages.Add("", "机械手引导", "");
                        this.tab_rightShow.TabPages.Add("", "下相机定位", "");
                        this.tab_rightShow.TabPages.Add("", "扫码", "");
                        //this.tab_rightShow.TabPages.Add("", "撕膜", "");
                        this.tab_leftShow.TabPages[0].Controls.Add(this.hWindow_upCam);
                        this.hWindow_upCam.Dock = DockStyle.Fill;
                        this.tab_leftShow.TabPages[1].Controls.Add(this.hWindowControl_guide);
                        this.hWindowControl_guide.Dock = DockStyle.Fill;
                        this.tab_rightShow.TabPages[0].Controls.Add(this.hWindow_downCam);
                        this.hWindow_downCam.Dock = DockStyle.Fill;
                        this.tab_rightShow.TabPages[1].Controls.Add(this.hWindow_scanCode);
                        this.hWindow_scanCode.Dock = DockStyle.Fill;
                        //this.tab_rightShow.TabPages[2].Controls.Add(this.hWindow_siMo);
                        this.hWindow_siMo.Dock = DockStyle.Fill;
                        this.lab_fixture.Text += "自动线Coil组装";
                        break;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("InitialProjectType初始化方法失败！" + ex.Message);
                logRecord.WriteLog("InitialProjectType初始化方法失败！" + ex.Message);
            }
        }
        private void SetStateShow(string state, Color foreColor)
        {
            this.AssemblyResult.Text = state;
            this.AssemblyResult.BackColor = foreColor;
        }
        private void JudgeFileKeepDays()
        {
            //图像保存期限
            if (Directory.Exists(ProjectInfo.Parameter.saveImagePath))
            {
                DirectoryInfo reportFolder = new DirectoryInfo(ProjectInfo.Parameter.saveImagePath);
                foreach (DirectoryInfo file in reportFolder.GetDirectories())  //遍历移动图像
                {
                    if (file.CreationTime < DateTime.Now.AddDays(-1 * ProjectInfo.Parameter.saveImageDays))
                        DeleteDir(file.FullName);
                }
            }
        }
        public static void DeleteDir(string file)
        {
            try
            {
                //去除文件夹和子文件的只读属性
                //去除文件夹的只读属性
                System.IO.DirectoryInfo fileInfo = new DirectoryInfo(file);
                fileInfo.Attributes = FileAttributes.Normal & FileAttributes.Directory;
                //去除文件的只读属性
                System.IO.File.SetAttributes(file, System.IO.FileAttributes.Normal);
                //判断文件夹是否还存在
                if (Directory.Exists(file))
                {
                    foreach (string f in Directory.GetFileSystemEntries(file))
                    {
                        if (File.Exists(f))
                        {
                            //如果有子文件删除文件
                            File.Delete(f);
                            Console.WriteLine(f);
                        }
                        else
                        {
                            //循环递归删除子文件夹
                            DeleteDir(f);
                        }
                    }
                    //删除空文件夹
                    Directory.Delete(file);
                }
            }
            catch (Exception ex) // 异常处理
            {
                MessageBox.Show("DeleteDir删除空文件夹失败！" + ex.Message);



            }
        }
        private void InitialHalconControls()
        {
            try
            {
                HOperatorSet.GenEmptyObj(out upCamROI_circle);
                HOperatorSet.GenEmptyObj(out upCamROI_line1);
                HOperatorSet.GenEmptyObj(out upCamROI_line2);
                HOperatorSet.GenEmptyObj(out upCamROI2_circle);
                HOperatorSet.GenEmptyObj(out upCamROI2_line1);
                HOperatorSet.GenEmptyObj(out upCamROI2_line2);
                HOperatorSet.GenEmptyObj(out downCamROI_circle);
                HOperatorSet.GenEmptyObj(out downCamROI_line1);
                HOperatorSet.GenEmptyObj(out downCamROI_line2);
                HOperatorSet.GenEmptyObj(out review1ROI_circle);
                HOperatorSet.GenEmptyObj(out review1ROI_line1);
                HOperatorSet.GenEmptyObj(out review1ROI_line2);
                HOperatorSet.GenEmptyObj(out review1ROI_line3);
                HOperatorSet.GenEmptyObj(out review1ROI_line4);
                HOperatorSet.GenEmptyObj(out review2ROI_circle);
                HOperatorSet.GenEmptyObj(out review3ROI_line1);
                HOperatorSet.GenEmptyObj(out review3ROI_line2);
                HOperatorSet.GenEmptyObj(out review2ROI_line1);
                HOperatorSet.GenEmptyObj(out review2ROI_line2);
                //初始化halcon窗体
                HOperatorSet.SetDraw(this.hWindow_downCam.HalconWindow, "margin");
                HOperatorSet.SetLineWidth(this.hWindow_downCam.HalconWindow, 2);
                HOperatorSet.SetColor(this.hWindow_downCam.HalconWindow, "blue");

                HOperatorSet.SetDraw(this.hWindow_upCam.HalconWindow, "margin");
                HOperatorSet.SetLineWidth(this.hWindow_upCam.HalconWindow, 2);
                HOperatorSet.SetColor(this.hWindow_upCam.HalconWindow, "blue");

                HOperatorSet.SetDraw(this.hWindow_scanCode.HalconWindow, "margin");
                HOperatorSet.SetLineWidth(this.hWindow_scanCode.HalconWindow, 2);
                HOperatorSet.SetColor(this.hWindow_scanCode.HalconWindow, "blue");

                HOperatorSet.SetDraw(this.hWindow_siMo.HalconWindow, "margin");
                HOperatorSet.SetLineWidth(this.hWindow_siMo.HalconWindow, 2);
                HOperatorSet.SetColor(this.hWindow_siMo.HalconWindow, "blue");

                HOperatorSet.SetDraw(this.hWindow_reviewEx3.HalconWindow, "margin");
                HOperatorSet.SetLineWidth(this.hWindow_reviewEx3.HalconWindow, 2);
                HOperatorSet.SetColor(this.hWindow_reviewEx3.HalconWindow, "blue");

                HOperatorSet.SetDraw(this.hWindowControl_glue.HalconWindow, "margin");
                HOperatorSet.SetLineWidth(this.hWindowControl_glue.HalconWindow, 2);
                HOperatorSet.SetColor(this.hWindowControl_glue.HalconWindow, "blue");

                HOperatorSet.SetDraw(this.hWindowControl_guide.HalconWindow, "margin");
                HOperatorSet.SetLineWidth(this.hWindowControl_guide.HalconWindow, 2);
                HOperatorSet.SetColor(this.hWindowControl_guide.HalconWindow, "blue");
            }
            catch (Exception)
            {
                MessageBox.Show("InitialHalconControls初始化halcon窗体或图形失败！");
                logRecord.WriteLog("InitialHalconControls初始化halcon窗体或图形失败！");
            }
        }
        private void LoadCalPara()
        {
            try
            {
                string calPath = System.Environment.CurrentDirectory + "\\calib.ini";
                if (!File.Exists(calPath))
                {
                    MessageBox.Show("标定文件不存在！");
                    logRecord.WriteLog("标定文件不存在！");
                    return;    //不存在文件返回false
                }
                ShareData.calParaIni = new CINIFactory(System.Environment.CurrentDirectory + "\\", "calib");  //初始化文件
                ShareData.calMoveStep = double.Parse(ShareData.calParaIni.ReadIniData("step", "move", ""));
                ShareData.calRotateStep = double.Parse(ShareData.calParaIni.ReadIniData("step", "rotate", ""));
                ShareData.downCamPixSize_X = double.Parse(ShareData.calParaIni.ReadIniData("camCalib", "dcam_X", ""));
                ShareData.downCamPixSize_Y = double.Parse(ShareData.calParaIni.ReadIniData("camCalib", "dcam_Y", ""));
                //ShareData.reviewPixSize_Y = double.Parse(ShareData.calParaIni.ReadIniData("camCalib", "review_Y", ""));

                ShareData.downCamPixSize_Phi = double.Parse(ShareData.calParaIni.ReadIniData("camCalib", "dcam_Phi", ""));
                ShareData.upCamPixSize1_Y = double.Parse(ShareData.calParaIni.ReadIniData("camCalib", "ucam1_Y", ""));
                ShareData.upCamPixSize2_Y = double.Parse(ShareData.calParaIni.ReadIniData("camCalib", "ucam2_Y", ""));

                ShareData.dowCamStandPos_X = double.Parse(ShareData.calParaIni.ReadIniData("spos", "dcam_X", ""));
                ShareData.dowCamStandPos_Y = double.Parse(ShareData.calParaIni.ReadIniData("spos", "dcam_Y", ""));
                ShareData.dowCamStandPos_Phi = double.Parse(ShareData.calParaIni.ReadIniData("spos", "dcam_Phi", ""));

                ShareData.dowCamStandPos2_X = double.Parse(ShareData.calParaIni.ReadIniData("spos", "dcam2_X", ""));
                ShareData.dowCamStandPos2_Y = double.Parse(ShareData.calParaIni.ReadIniData("spos", "dcam2_Y", ""));
                ShareData.dowCamStandPos2_Phi = double.Parse(ShareData.calParaIni.ReadIniData("spos", "dcam2_Phi", ""));

                ShareData.upCamStandPos1_X = double.Parse(ShareData.calParaIni.ReadIniData("spos", "ucam1_X", ""));
                ShareData.upCamStandPos1_Y = double.Parse(ShareData.calParaIni.ReadIniData("spos", "ucam1_Y", ""));
                ShareData.upCamStandPos1_Phi = double.Parse(ShareData.calParaIni.ReadIniData("spos", "ucam1_Phi", ""));

                ShareData.upCamStandPos2_X = double.Parse(ShareData.calParaIni.ReadIniData("spos", "ucam2_X", ""));
                ShareData.upCamStandPos2_Y = double.Parse(ShareData.calParaIni.ReadIniData("spos", "ucam2_Y", ""));
                ShareData.upCamStandPos2_Phi = double.Parse(ShareData.calParaIni.ReadIniData("spos", "ucam2_Phi", ""));
                //吸嘴的旋转中心
                ShareData.rotateCenter_X = double.Parse(ShareData.calParaIni.ReadIniData("rotate", "center_X", ""));
                ShareData.rotateCenter_Y = double.Parse(ShareData.calParaIni.ReadIniData("rotate", "center_Y", ""));

            }
            catch (Exception ex)
            {

                AddFormLog("LoadCalPara加载标定参数失败！" + ex.Message);
                logRecord.WriteLog("LoadCalPara加载标定参数失败！" + ex.Message);
            }
        }
        private void AddFormLog(string logInfo)
        {
            //20200704于
            AddFormLog(logInfo, SystemColors.Window);
        }

        public static object lockObject = new object();
        protected void AddFormLog(string logInfo, Color color)
        {
            lock (lockObject)
            {
                this.Invoke(new Action(() =>
                {
                    //增加窗体log输出
                    if (this.lbMsg.Items.Count > 50)
                    {
                        this.lbMsg.Items.Clear();
                    }
                    this.lbMsg.Items.Add(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss fff   ") + logInfo + Environment.NewLine);

                    this.lbMsg.SelectedIndex = lbMsg.Items.Count - 1;
                }));
            }
        }

        //屏蔽右上角关闭按钮
        private const int CP_NOCLOSE_BUTTON = 0x200;
        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams myCp = base.CreateParams;
                myCp.ClassStyle = myCp.ClassStyle | CP_NOCLOSE_BUTTON;
                return myCp;
            }
        }
        #endregion

        #region 事件和处理线程

        void MvsCameral_captureImage(int cameralIndex, Bitmap image)
        {
            //相机回调
            HObject ho_Image = halconAlgorithm.Bitmap2HObject(image);  //用于实时显示图像
            if (cameralIndex == ProjectInfo.Parameter.downCamIndex)
            {
                //if (downCamStatus == WorkStatus.下相机组装 || downCamStatus == WorkStatus.撕膜工位 || downCamStatus == WorkStatus.扫码)
                if (downCamStatus == WorkStatus.下相机组装)
                {
                    downCamQueue.Enqueue(ho_Image);
                }

                if (downCamStatus == WorkStatus.扫码)
                {
                    CodedownCamQueue.Enqueue(ho_Image);
                    this.logRecord.WriteLog("下相机扫码:" + downCamStatus.ToString());
                }

            }
            if (cameralIndex == ProjectInfo.Parameter.upCamIndex)
            {
                if (upCamStatus == WorkStatus.上相机组装1 || upCamStatus == WorkStatus.上相机组装2)
                    upCamQueue.Enqueue(ho_Image);
            }
            if (cameralIndex == ProjectInfo.Parameter.guideCamIndex)
            {
                if (detectCamStatus == WorkStatus.机械手引导)
                    detectCamQueue.Enqueue(ho_Image);
            }
        }
        private void StartProcessDownCam()//组装过程
        {

            HObject h_Image = null;
            HObject code_Image = null;

            while (threadBusy)
            {
                try
                {
                    if (!downCamQueue.IsEmpty)
                    {
                        bool nflag = downCamQueue.TryDequeue(out h_Image);
                        if (!nflag || h_Image == null) continue;

                        #region 如果下相机拍照进入处理
                        if (downCamStatus == WorkStatus.下相机组装)
                        {
                            {
                                //增加处理函数获得位置........................................
                                #region 下相机定位算法
                                HObject ho_fitCircleContour = null;
                                HObject ho_fitLine1Contour = null;
                                HOperatorSet.GenEmptyObj(out ho_fitCircleContour);
                                HOperatorSet.GenEmptyObj(out ho_fitLine1Contour);
                                try
                                {
                                    if (downCamImage == null) HOperatorSet.GenEmptyObj(out downCamImage);
                                    downCamImage.Dispose();
                                    downCamImage = h_Image.Clone();
                                    double circle_X = 0;
                                    double circle_Y = 0;
                                    double angle = 0;
                                    string bugInfo = "";
                                    //halconAlgorithm.ho_AdaptiveImage(this.hWindow_downCam, hv_ImageWidth, hv_ImageHeight);     //图像自适应
                                    this.hWindow_downCam.HalconWindow.ClearWindow();
                                    HOperatorSet.DispObj(h_Image, this.hWindow_downCam.HalconWindow);     //显示图像
                                    this.hWindow_downCam.SetFullImagePart();
                                    if (ShareData.projectItem == ShareData.ItemType.自动线coil组装)
                                    {
                                        //只用到一个圆和一条线进行定位，针对coil检测
                                        //if (true)
                                        if (halconAlgorithm.GetCoilPosition_match(h_Image, hv_downCamModel, ProjectInfo.Parameter.downCamLocateMatchPara, ProjectInfo.Parameter.downCamLocateFitCirclePara,
                                          ProjectInfo.Parameter.downCamLocateFitLine1Para, downCamROI_circle, downCamROI_line1, out ho_fitCircleContour, out ho_fitLine1Contour,
                                                out circle_X, out circle_Y, out angle, out bugInfo))
                                        {
                                            //显示图像及绘制的图形
                                            HOperatorSet.DispObj(ho_fitCircleContour, this.hWindow_downCam.HalconWindow);
                                            HOperatorSet.DispObj(ho_fitLine1Contour, this.hWindow_downCam.HalconWindow);
                                            downCamPos_X = circle_X;
                                            downCamPos_Y = circle_Y;
                                            downCamPos_Phi = angle;
                                            downCamLocatDown = true;
                                            //UPH-  Thread.Sleep(80);
                                            //SendPhotoDownSignal(4, 1);            //发送下相机拍照完成信号
                                            AddFormLog("下相机组装位置：X:" + circle_X.ToString("f3") + ";Y:" + circle_Y.ToString("f3") + ";Phi:" + angle.ToString("f4"));
                                            logRecord.WriteLog("下相机组装位置：X:" + circle_X.ToString("f3") + ";Y:" + circle_Y.ToString("f3") + ";Phi:" + angle.ToString("f4"));

                                        }
                                        else
                                        {
                                            bDownNG = true;
                                            downCamLocatDown = false;
                                            //SendPhotoDownSignal(4, 1);            //发送下相机拍照完成信号
                                            //AddFormLog("下相机拍照完成信号");
                                            //logRecord.WriteLog("下相机拍照完成信号");
                                            SendAndShowPhotoError(4, bugInfo);             //发送Pc异常
                                            //                                         Task.Factory.StartNew(
                                            //() =>
                                            //{
                                            SaveBitmapError(downCamImage, "DownCam_Error", this.hWindow_downCam.HalconWindow);
                                            logRecord.WriteLog("下相机异常图片保存！");
                                            //});
                                            continue;

                                        }
                                    }
                                }
                                catch (Exception ex)
                                {
                                    bDownNG = true;
                                    downCamLocatDown = false;
                                    //SendPhotoDownSignal(4, 1);            //发送下相机拍照完成信号
                                    //AddFormLog("下相机拍照完成信号");
                                    //logRecord.WriteLog("下相机拍照完成信号");
                                    SendAndShowPhotoError(4, "下相机定位异常，" + ex.Message);             //发送Pc异常
                                    //                            Task.Factory.StartNew(
                                    //() =>
                                    //{
                                    SaveBitmapError(downCamImage, "DownCam_Error", this.hWindow_downCam.HalconWindow);
                                    logRecord.WriteLog("下相机异常图片保存！");
                                    //});

                                }
                                //finally
                                //{
                                //    ho_fitCircleContour.Dispose();
                                //    ho_fitLine1Contour.Dispose();
                                //}


                                #endregion

                                if (!ShareData.isRepet)//不是老化流程则执行拍扫码拍照
                                {
                                    //扫码工位
                                    downCamStatus = WorkStatus.扫码;
                                    ShareData.MvsCameral.SetHKCamExposure(ProjectInfo.Parameter.downCamIndex, ProjectInfo.Parameter.scanCodeCamExposure);   //设置曝光
                                    ShareData.MvsCameral.SetHKCamExposure(ProjectInfo.Parameter.downCamIndex, ProjectInfo.Parameter.scanCodeCamGamma);      //设置伽马
                                    Thread.Sleep(10);
                                    ShareData.MvsCameral.SoftTriggerOnce(ProjectInfo.Parameter.downCamIndex);        //下相机软触发一次                            
                                    this.logRecord.WriteLog("开始扫码拍照！");
                                    this.Invoke(new Action(() =>
                                    {
                                        AddFormLog("开始扫码拍照！");
                                    }));
                                }
                            }
                        }
                        #endregion

                    }
                    if (downCamStatus == WorkStatus.扫码 && !CodedownCamQueue.IsEmpty)
                    {
                        bool nflag = CodedownCamQueue.TryDequeue(out code_Image);
                        if (!nflag || code_Image == null) continue;

                        #region 下相机撕膜算法
                        try
                        {
                            //if (codeImage == null) HOperatorSet.GenEmptyObj(out codeImage);
                            //codeImage.Dispose();
                            codeImage = code_Image.Clone();
                            HTuple hv_result = null;
                            HTuple hv_gray = null;
                            HObject ho_SiMoROI = null;
                            halconAlgorithm.JudgeTapeExist(code_Image, hv_downCamModel, ProjectInfo.Parameter.downCamLocateMatchPara, out hv_result, out hv_gray, out ho_SiMoROI);
                            if (hv_result == 0)   //增加撕膜算法
                            {
                                //膜已撕掉
                                SendSiMoReusltSignal(1);
                                AddFormLog("发送撕膜成功信号,灰度值：" + hv_gray.D.ToString());
                                logRecord.WriteLog("发送撕膜成功信号,灰度值" + hv_gray.D.ToString("f1"));
                                downCamSiMoDown = true;
                                this.Invoke(new Action(() =>
                                {
                                    this.pnl_siMoStatus.BackColor = Color.Lime;
                                }));

                                this.hWindow_scanCode.HalconWindow.ClearWindow();
                                HOperatorSet.SetColor(this.hWindow_scanCode.HalconWindow, "cyan");
                                HOperatorSet.DispObj(code_Image, this.hWindow_scanCode.HalconWindow);
                                HOperatorSet.DispObj(ho_SiMoROI, this.hWindow_scanCode.HalconWindow);
                                this.hWindow_scanCode.SetFullImagePart();

                            }
                            else
                            {
                                //膜未撕掉
                                SendSiMoReusltSignal(2);            //发送撕膜结果信号，2为失败信号，1为撕膜成功信号
                                AddFormLog("撕膜失败！灰度值：" + hv_gray.D.ToString(), Color.Red);
                                logRecord.WriteLog("撕膜失败！灰度值：" + hv_gray.D.ToString("f1"));
                                downCamSiMoDown = false;
                                SaveBitmapError(codeImage, "DownCam_SiMo_Error", this.hWindow_downCam.HalconWindow);
                                logRecord.WriteLog("下相机撕膜异常图片保存！");
                                this.Invoke(new Action(() =>
                                {
                                    this.pnl_siMoStatus.BackColor = Color.Red;
                                }));
                                HOperatorSet.SetColor(this.hWindow_downCam.HalconWindow, "orange");
                                HOperatorSet.DispObj(ho_SiMoROI, this.hWindow_downCam.HalconWindow);
                            }

                            ho_SiMoROI.Dispose();
                            hv_result.Dispose();
                            hv_gray.Dispose();
                        }
                        catch (Exception ex)
                        {
                            SendSiMoReusltSignal(2);            //发送撕膜结果信号，2为失败信号，1为撕膜成功信号
                            this.Invoke(new Action(() =>
                            {
                                this.pnl_siMoStatus.BackColor = Color.Red;
                            }));
                            AddFormLog("撕膜算法异常");
                            logRecord.WriteLog("撕膜算法异常!" + ex.Message);
                            downCamSiMoDown = false;
                            SaveBitmapError(codeImage, "DownCam_SiMo_Error", this.hWindow_downCam.HalconWindow);
                            logRecord.WriteLog("下相机撕膜异常图片保存！");
                        }

                        #endregion

                        if (downCamSiMoDown)
                        {
                            #region 扫码工位

                            try
                            {
                               // this.hWindow_scanCode.HalconWindow.ClearWindow();
                                //HOperatorSet.DispObj(code_Image, this.hWindow_scanCode.HalconWindow);     //显示图像
                                //this.hWindow_scanCode.SetFullImagePart();
                                if (checkBox_SN.Checked)
                                {
                                    HTuple hv_code = null;
                                    HTuple hv_result = null;
                                    ShareData.strCoilCode = "";
                                    this.tB_coilCode.Text = ShareData.strCoilCode;
                                    halconAlgorithm.FindCode(code_Image, out hv_code, out hv_result);
                                    if (hv_result == 0)
                                    {
                                        //成功扫到码
                                        AddFormLog("扫码成功，CoilSN：" + hv_code.S);
                                        Thread.Sleep(50);
                                        SendScanCodeResultSignal(1);                   //发送扫码成功信号
                                        //UPH-    Thread.Sleep(50);
                                        ShareData.strCoilCode = hv_code.S;
                                        //john  20200809
                                        SendScanCodeStr(ShareData.strCoilCode);                     //发送码
                                        AddFormLog("发送CoilSN：" + ShareData.strCoilCode);
                                        this.logRecord.WriteLog("发送扫码成功信号！发送Coil条码：" + ShareData.strCoilCode);
                                        downCamCodeDown = true;
                                        Thread.Sleep(50);

                                        this.Invoke(new Action(() =>
                                        {
                                            this.tB_coilCode.Text = ShareData.strCoilCode;
                                        }));


                                        SendPhotoDownSignal(4, 1);            //发送下相机拍照完成信号
                                        AddFormLog("发送下相机拍照完成信号");
                                        logRecord.WriteLog("发送下相机拍照完成信号");

                                    }
                                    else
                                    {
                                        //扫码失败
                                        SendScanCodeResultSignal(2);                  //发送扫码失败信号
                                        AddFormLog("扫码失败！");
                                        this.logRecord.WriteLog("发送扫码失败信号！");
                                        downCamCodeDown = false;
                                        SaveBitmapError(codeImage, "Code_Error", this.hWindow_downCam.HalconWindow);
                                        this.logRecord.WriteLog("保存扫码失败图片！");
                                    }

                                }
                            }
                            catch (Exception ex)
                            {
                                SendScanCodeResultSignal(2);                       //发送扫码失败信号
                                AddFormLog("发送扫码失败信号！");
                                this.logRecord.WriteLog("发送扫码失败信号！");
                                downCamCodeDown = false;
                                if (codeImage != null)
                                {
                                    SaveBitmapError(codeImage, "Code_Error", this.hWindow_downCam.HalconWindow);
                                    this.logRecord.WriteLog("保存扫码失败图片！");
                                }
                            }
                            #endregion
                        }


                    }

                    int curChannelDown = -1;
                    if (downCamCodeDown)
                    {

                        channelQueue.TryDequeue(out curChannelDown);
                        if (curChannelDown == 1)   //流道1
                        {
                            #region 空跑1
                            //if (bDownNG)
                            //{
                            //    bDownNG = false;

                            //    offset_X = 0.1;
                            //    offset_Y = 0.1;
                            //    offset_Phi = 0.1;

                            //    this.Invoke(new Action(() =>
                            //    {
                            //        this.tB_offsetX.Text = offset_X.ToString("f4");
                            //        this.tB_offsetY.Text = offset_Y.ToString("f4");
                            //        this.tB_offsetPhi.Text = offset_Phi.ToString("f4");
                            //        this.lab_curChannel.Text = "当前组装流道：流道一";
                            //    }));

                            //    {
                            //        offset_X = 0.1;
                            //        offset_Y = 0.1;
                            //        offset_Phi = 0.1;

                            //        Thread.Sleep(50);
                            //        //向plc寄存器地址写入数据                                    
                            //        SetAssemblyOffsetCoor((int)(offset_X * 1000), (int)(offset_Y * 1000), (int)(offset_Phi * 1000));    //分别*1000,转化为mm，读数*1000,转为毫度
                            //        Thread.Sleep(50);                                                                         //延时50ms再发送重置信号
                            //        NoticeAssemblyMoveSignal(1);                                          //通知plc走位信号   
                            //        Thread.Sleep(50);

                            //        upCamLocatDown1 = false;                                                                   //重置上相机获取位置信号
                            //        angleRegulateNum = 0;
                            //        proTotalNum++;
                            //        this.Invoke(new Action(() =>
                            //        {
                            //            this.tB_proTotalNum.Text = proTotalNum.ToString();
                            //        }));
                            //        AddFormLog("发送位置偏差_1;" + "offset_X:" + offset_X.ToString() + "offset_Y:" + offset_Y.ToString() + "offset_Phi:" + offset_Phi.ToString());
                            //        this.logRecord.WriteLog("发送位置偏差_1;" + "offset_X:" + offset_X.ToString() + "offset_Y:" + offset_Y.ToString() + "offset_Phi:" + offset_Phi.ToString());

                            //        //角度差超出上限，当作异常信号     
                            //        //SendAndShowPhotoError(4, "角度偏差超出上限1！");             //先发上相机组装异常
                            //        //Thread.Sleep(50);
                            //        //SendAndShowPhotoError(3, "角度偏差超出上限1！");             //再发下相机组装异常
                            //        //angleRegulateNum = 0;
                            //        //upCamLocatDown1 = false;
                            //    }
                            //    continue;
                            //}


                            if (isEmptyRun)
                            {
                                //空跑模式            
                                downCamLocatDown = false;
                                downCamSiMoDown = false;
                                downCamCodeDown = false;
                                upCamLocatDown1 = false;
                                Thread.Sleep(200);
                                SetAssemblyOffsetCoor((int)(0.1 * 1000), (int)(0.2 * 1000), (int)(0.1 * 1000));    //分别*1000,转化为mm，读数*1000,转为毫度
                                Thread.Sleep(80);                                                                         //延时50ms再发送重置信号
                                NoticeAssemblyMoveSignal(1);                                          //通知plc走位信号   
                                AddFormLog("发送位置补偿信号1");
                                logRecord.WriteLog("发送位置补偿信号1");
                                continue;
                            }
                            #endregion
                            #region 计算对位偏移量-流道1
                            downCamLocatDown = false;
                            downCamSiMoDown = false;
                            downCamCodeDown = false;
                            try
                            {
                                //计算旋转角度，对偏移角度angle进行判断
                                HTuple downCamStandRobot_X, downCamStandRobot_Y = 0;
                                HTuple downCamCurRobot_X, downCamCurRobot_Y = 0;
                                HTuple upCamStandRobot_X, upCamStandRobot_Y = 0;
                                HTuple upCamCurRobot_X, upCamCurRobot_Y = 0;

                                HOperatorSet.AffineTransPoint2d(downCamHomMat2D, ShareData.dowCamStandPos_X, ShareData.dowCamStandPos_Y, out downCamStandRobot_X, out downCamStandRobot_Y);   //下相机的标准位置从像素坐标转机械手坐标
                                HOperatorSet.AffineTransPoint2d(upCam1HomMat2D, ShareData.upCamStandPos1_X, ShareData.upCamStandPos1_Y, out upCamStandRobot_X, out upCamStandRobot_Y);  //上相机的标准位置从像素坐标转机械手坐标
                                //halconAlgorithm.DownCamCoorTrans(ShareData.dowCamStandPos_X, ShareData.dowCamStandPos_Y, out downCamStandRobot_X, out downCamStandRobot_Y);        
                                //halconAlgorithm.UpCam2CoorTrans(ShareData.upCamStandPos2_X, ShareData.upCamStandPos2_Y, out upCamStandRobot_X, out upCamStandRobot_Y);            
                                HOperatorSet.AffineTransPoint2d(upCam1HomMat2D, upCamPos1_X, upCamPos1_Y, out upCamCurRobot_X, out upCamCurRobot_Y);   //上相机的当前位置从像素坐标转机械手坐标
                                //halconAlgorithm.UpCam2CoorTrans(upCamPos2_X, upCamPos2_Y, out upCamCurRobot_X, out upCamCurRobot_Y);                                            

                                double upCamOffset_X = (upCamCurRobot_X - upCamStandRobot_X);         //上相机x轴方向的偏差,使用Y轴方向的像素当量
                                double upCamOffset_Y = (upCamCurRobot_Y - upCamStandRobot_Y);         //上相机y轴方向的偏差，世界坐标

                                double downCamOffset_Phi = (ShareData.dowCamStandPos_Phi - downCamPos_Phi) * 1;
                                double upCamOffset_Phi = ShareData.upCamStandPos1_Phi * 1 - upCamPos1_Phi;  //上相机角度方向的偏差，
                                offset_Phi = (upCamOffset_Phi + downCamOffset_Phi) + ProjectInfo.Parameter.buChang_Angle1 * Math.PI / 180; //角度总偏差，并进行补偿

                                HTuple hv_HomMat2D = new HTuple();
                                hv_HomMat2D.Dispose();
                                HTuple hv_CoorTrans_X;
                                HTuple hv_CoorTrans_Y;
                                HOperatorSet.VectorAngleToRigid(ShareData.rotateCenter_X, ShareData.rotateCenter_Y, 0, ShareData.rotateCenter_X, ShareData.rotateCenter_Y, offset_Phi, out hv_HomMat2D);
                                HOperatorSet.AffineTransPixel(hv_HomMat2D, downCamPos_X, downCamPos_Y, out hv_CoorTrans_X, out hv_CoorTrans_Y);   //对coil中心沿着吸嘴的旋转中心进行旋转

                                HOperatorSet.AffineTransPoint2d(downCamHomMat2D, hv_CoorTrans_X, hv_CoorTrans_Y, out downCamCurRobot_X, out downCamCurRobot_Y); //下相机的当前位置从像素坐标转机械手坐标
                                //halconAlgorithm.DownCamCoorTrans(hv_CoorTrans_X, hv_CoorTrans_Y, out downCamCurRobot_X, out downCamCurRobot_Y); //下相机的当前位置从像素坐标转机械手坐标
                                double downCamOffset_X = (downCamCurRobot_X - downCamStandRobot_X);           //下相机x轴方向的偏差,世界坐标
                                double downCamOffset_Y = (downCamCurRobot_Y - downCamStandRobot_Y);           //下相机y轴方向的偏差，世界坐标

                                offset_X = upCamOffset_X - downCamOffset_X + ProjectInfo.Parameter.buChang_X1;    //x轴方向总偏差
                                offset_Y = upCamOffset_Y - downCamOffset_Y + ProjectInfo.Parameter.buChang_Y1;    //y轴方向总偏差
                                offset_Phi = offset_Phi * 180 / Math.PI;                                          //将弧度转换为角度

                                this.Invoke(new Action(() =>
                                {
                                    this.tB_offsetX.Text = offset_X.ToString("f4");
                                    this.tB_offsetY.Text = offset_Y.ToString("f4");
                                    this.tB_offsetPhi.Text = offset_Phi.ToString("f4");
                                    this.lab_curChannel.Text = "当前组装流道：流道一";
                                }));

                                if (Math.Abs(offset_Phi) < ProjectInfo.Parameter.maxAngleOffset && Math.Abs(offset_X) < ProjectInfo.Parameter.maxXOffset && Math.Abs(offset_Y) < ProjectInfo.Parameter.maxYOffset)
                                {
                                    //角度矫正范围已经处于OK范围内，发送角度OK信号    
                                    //Thread.Sleep(20);
                                    // SendPhotoDownSignal(4, 1);            //发送下相机拍照完成信号
                                    //UPH-    Thread.Sleep(50);
                                    //向plc寄存器地址写入数据                                    
                                    SetAssemblyOffsetCoor((int)(offset_X * 1000), (int)(offset_Y * 1000), (int)(offset_Phi * 1000));    //分别*1000,转化为mm，读数*1000,转为毫度
                                    this.logRecord.WriteLog("发送位置偏差_1;" + "offset_X:" + offset_X.ToString() + "offset_Y:" + offset_Y.ToString() + "offset_Phi:" + offset_Phi.ToString());
                                
                                    Thread.Sleep(50);                                                                         //延时50ms再发送重置信号
                                    NoticeAssemblyMoveSignal(1);                                          //通知plc走位信号   
                                    this.logRecord.WriteLog("发送走位信号1" );
                                
                                    upCamLocatDown1 = false;                                                                   //重置上相机获取位置信号
                                    angleRegulateNum = 0;
                                    proTotalNum++;
                                    this.Invoke(new Action(() =>
                                    {
                                        this.tB_proTotalNum.Text = proTotalNum.ToString();
                                    }));
                                    AddFormLog("发送位置偏差_1;" + "offset_X:" + offset_X.ToString() + "offset_Y:" + offset_Y.ToString() + "offset_Phi:" + offset_Phi.ToString());
                                    //this.logRecord.WriteLog("发送位置偏差_1;" + "offset_X:" + offset_X.ToString() + "offset_Y:" + offset_Y.ToString() + "offset_Phi:" + offset_Phi.ToString());
                                }
                                else
                                {
                                    //角度差超出上限，当作异常信号     
                                    SendAndShowPhotoError(4, "位置偏差超出上限1！");             //先发上相机组装异常
                                    Thread.Sleep(50);
                                    SendAndShowPhotoError(3, "位置偏差超出上限1！");             //再发下相机组装异常
                                    angleRegulateNum = 0;
                                    upCamLocatDown1 = false;
                                }
                            }
                            catch (Exception ex)
                            {
                                SendAndShowPhotoError(4, "计算偏差出现异常_1！" + ex.Message);             //先发上相机组装异常
                                Thread.Sleep(50);
                                SendAndShowPhotoError(3, "计算偏差出现异常_1！" + ex.Message);             //再发下相机组装异常
                                angleRegulateNum = 0;
                            }
                            finally
                            {
                                //测试
                                //Task.Factory.StartNew(
                                // () =>
                                //   {
                                SaveBitmap(ho_UpCam1, "UpCam", this.hWindow_upCam.HalconWindow);
                                SaveBitmap(downCamImage, "downCam", this.hWindow_downCam.HalconWindow);
                                SaveBitmap(codeImage, "Code", this.hWindow_scanCode.HalconWindow);
                                // });

                            }
                            #endregion
                        }
                        else if (curChannelDown == 2)   //流道2
                        {
                            #region 空跑2
                            //if (bDownNG)
                            //{
                            //    bDownNG = false;

                            //    offset_X = 0.1;
                            //    offset_Y = 0.1;
                            //    offset_Phi = 0.1;

                            //    this.Invoke(new Action(() =>
                            //    {
                            //        this.tB_offsetX.Text = offset_X.ToString("f4");
                            //        this.tB_offsetY.Text = offset_Y.ToString("f4");
                            //        this.tB_offsetPhi.Text = offset_Phi.ToString("f4");
                            //        this.lab_curChannel.Text = "当前组装流道：流道二";
                            //    }));


                            //    {
                            //        //角度矫正范围已经处于OK范围内，发送角度OK信号    
                            //        //Thread.Sleep(20);
                            //        // SendPhotoDownSignal(4, 1);            //发送下相机拍照完成信号
                            //        Thread.Sleep(50);
                            //        //向plc寄存器地址写入数据                                    
                            //        SetAssemblyOffsetCoor((int)(offset_X * 1000), (int)(offset_Y * 1000), (int)(offset_Phi * 1000));    //分别*1000,转化为mm，读数*1000,转为毫度
                            //        Thread.Sleep(50);                                                                         //延时50ms再发送重置信号
                            //        NoticeAssemblyMoveSignal(1);                                          //通知plc走位信号   
                            //        upCamLocatDown2 = false;                                                                   //重置上相机获取位置信号
                            //        angleRegulateNum = 0;
                            //        proTotalNum++;
                            //        this.Invoke(new Action(() =>
                            //        {
                            //            this.tB_proTotalNum.Text = proTotalNum.ToString();
                            //        }));
                            //        AddFormLog("发送位置偏差_2;" + "offset_X:" + offset_X.ToString() + "offset_Y:" + offset_Y.ToString() + "offset_Phi:" + offset_Phi.ToString());
                            //        this.logRecord.WriteLog("发送位置偏差_2;" + "offset_X:" + offset_X.ToString() + "offset_Y:" + offset_Y.ToString() + "offset_Phi:" + offset_Phi.ToString());
                            //    }
                            //    continue;
                            //}


                            if (isEmptyRun)
                            {
                                //空跑模式            
                                downCamLocatDown = false;
                                downCamSiMoDown = false;
                                downCamCodeDown = false;
                                upCamLocatDown2 = false;
                                Thread.Sleep(200);
                                SetAssemblyOffsetCoor((int)(0.1 * 1000), (int)(0.2 * 1000), (int)(0.1 * 1000));    //分别*1000,转化为mm，读数*1000,转为毫度
                                Thread.Sleep(80);                                                                         //延时50ms再发送重置信号
                                NoticeAssemblyMoveSignal(1);                                          //通知plc走位信号   
                                AddFormLog("发送位置补偿信号2");
                                logRecord.WriteLog("发送位置补偿信号2");
                                continue;
                            }
                            #endregion
                            #region 计算对位偏移量-流道2
                            downCamLocatDown = false;
                            downCamSiMoDown = false;
                            downCamCodeDown = false;
                            try
                            {
                                //计算旋转角度，对偏移角度angle进行判断
                                HTuple downCamStandRobot_X, downCamStandRobot_Y = 0;
                                HTuple downCamCurRobot_X, downCamCurRobot_Y = 0;
                                HTuple upCamStandRobot_X, upCamStandRobot_Y = 0;
                                HTuple upCamCurRobot_X, upCamCurRobot_Y = 0;

                                HOperatorSet.AffineTransPoint2d(downCamHomMat2D, ShareData.dowCamStandPos2_X, ShareData.dowCamStandPos2_Y, out downCamStandRobot_X, out downCamStandRobot_Y);   //下相机的标准位置从像素坐标转机械手坐标
                                HOperatorSet.AffineTransPoint2d(upCam2HomMat2D, ShareData.upCamStandPos2_X, ShareData.upCamStandPos2_Y, out upCamStandRobot_X, out upCamStandRobot_Y);         //上相机的标准位置从像素坐标转机械手坐标
                                //halconAlgorithm.DownCamCoorTrans(ShareData.dowCamStandPos_X, ShareData.dowCamStandPos_Y, out downCamStandRobot_X, out downCamStandRobot_Y);        
                                //halconAlgorithm.UpCam2CoorTrans(ShareData.upCamStandPos2_X, ShareData.upCamStandPos2_Y, out upCamStandRobot_X, out upCamStandRobot_Y);            
                                HOperatorSet.AffineTransPoint2d(upCam2HomMat2D, upCamPos2_X, upCamPos2_Y, out upCamCurRobot_X, out upCamCurRobot_Y);                                         //上相机的当前位置从像素坐标转机械手坐标
                                //halconAlgorithm.UpCam2CoorTrans(upCamPos2_X, upCamPos2_Y, out upCamCurRobot_X, out upCamCurRobot_Y);                                            

                                double upCamOffset_X = (upCamCurRobot_X - upCamStandRobot_X);         //上相机x轴方向的偏差,使用Y轴方向的像素当量
                                double upCamOffset_Y = (upCamCurRobot_Y - upCamStandRobot_Y);         //上相机y轴方向的偏差，世界坐标

                                double downCamOffset_Phi = (ShareData.dowCamStandPos2_Phi - downCamPos_Phi) * 1;
                                double upCamOffset_Phi = ShareData.upCamStandPos2_Phi * 1 - upCamPos2_Phi;                                //上相机角度方向的偏差，
                                offset_Phi = (upCamOffset_Phi + downCamOffset_Phi) + ProjectInfo.Parameter.buChang_Angle2 * Math.PI / 180;     //角度总偏差，并进行补偿

                                HTuple hv_HomMat2D = new HTuple();
                                hv_HomMat2D.Dispose();
                                HTuple hv_CoorTrans_X;
                                HTuple hv_CoorTrans_Y;
                                HOperatorSet.VectorAngleToRigid(ShareData.rotateCenter_X, ShareData.rotateCenter_Y, 0, ShareData.rotateCenter_X, ShareData.rotateCenter_Y, offset_Phi, out hv_HomMat2D);
                                HOperatorSet.AffineTransPixel(hv_HomMat2D, downCamPos_X, downCamPos_Y, out hv_CoorTrans_X, out hv_CoorTrans_Y);   //对coil中心沿着吸嘴的旋转中心进行旋转

                                HOperatorSet.AffineTransPoint2d(downCamHomMat2D, hv_CoorTrans_X, hv_CoorTrans_Y, out downCamCurRobot_X, out downCamCurRobot_Y);        //下相机的当前位置从像素坐标转机械手坐标
                                //halconAlgorithm.DownCamCoorTrans(hv_CoorTrans_X, hv_CoorTrans_Y, out downCamCurRobot_X, out downCamCurRobot_Y);                      //下相机的当前位置从像素坐标转机械手坐标
                                double downCamOffset_X = (downCamCurRobot_X - downCamStandRobot_X);           //下相机x轴方向的偏差,世界坐标
                                double downCamOffset_Y = (downCamCurRobot_Y - downCamStandRobot_Y);           //下相机y轴方向的偏差，世界坐标

                                offset_X = upCamOffset_X - downCamOffset_X + ProjectInfo.Parameter.buChang_X2;    //x轴方向总偏差
                                offset_Y = upCamOffset_Y - downCamOffset_Y + ProjectInfo.Parameter.buChang_Y2;    //y轴方向总偏差
                                offset_Phi = offset_Phi * 180 / Math.PI;                                          //将弧度转换为角度

                                this.Invoke(new Action(() =>
                                {
                                    this.tB_offsetX.Text = offset_X.ToString("f4");
                                    this.tB_offsetY.Text = offset_Y.ToString("f4");
                                    this.tB_offsetPhi.Text = offset_Phi.ToString("f4");
                                    this.lab_curChannel.Text = "当前组装流道：流道二";
                                }));

                                if (Math.Abs(offset_Phi) < ProjectInfo.Parameter.maxAngleOffset && Math.Abs(offset_X) < ProjectInfo.Parameter.maxXOffset && Math.Abs(offset_Y) < ProjectInfo.Parameter.maxYOffset)
                                {
                                    //角度矫正范围已经处于OK范围内，发送角度OK信号    
                                    //Thread.Sleep(20);
                                    // SendPhotoDownSignal(4, 1);            //发送下相机拍照完成信号
                                    AddFormLog("发送下相机拍照完成信号");
                                    logRecord.WriteLog("发送下相机拍照完成信号");
                                    //UPH-   Thread.Sleep(50);
                                    //向plc寄存器地址写入数据                                    
                                    SetAssemblyOffsetCoor((int)(offset_X * 1000), (int)(offset_Y * 1000), (int)(offset_Phi * 1000));    //分别*1000,转化为mm，读数*1000,转为毫度
                                    Thread.Sleep(50);                                                                         //延时50ms再发送重置信号
                                    NoticeAssemblyMoveSignal(1);                                          //通知plc走位信号   
                                    upCamLocatDown2 = false;                                                                   //重置上相机获取位置信号
                                    angleRegulateNum = 0;
                                    proTotalNum++;
                                    this.Invoke(new Action(() =>
                                    {
                                        this.tB_proTotalNum.Text = proTotalNum.ToString();
                                    }));
                                    AddFormLog("发送位置偏差_2;" + "offset_X:" + offset_X.ToString() + "offset_Y:" + offset_Y.ToString() + "offset_Phi:" + offset_Phi.ToString());
                                    this.logRecord.WriteLog("发送位置偏差_2;" + "offset_X:" + offset_X.ToString() + "offset_Y:" + offset_Y.ToString() + "offset_Phi:" + offset_Phi.ToString());
                                }
                                else
                                {
                                    //offset_X = 0.1;
                                    //offset_Y = 0.1;
                                    //offset_Phi = 0.1;
                                    //Thread.Sleep(50);
                                    ////向plc寄存器地址写入数据                                    
                                    //SetAssemblyOffsetCoor((int)(offset_X * 1000), (int)(offset_Y * 1000), (int)(offset_Phi * 1000));    //分别*1000,转化为mm，读数*1000,转为毫度
                                    //Thread.Sleep(50);                                                                         //延时50ms再发送重置信号
                                    //NoticeAssemblyMoveSignal(1);                                          //通知plc走位信号   
                                    //upCamLocatDown2 = false;                                                                   //重置上相机获取位置信号
                                    //angleRegulateNum = 0;
                                    //proTotalNum++;
                                    //this.Invoke(new Action(() =>
                                    //{
                                    //    this.tB_proTotalNum.Text = proTotalNum.ToString();
                                    //}));
                                    //AddFormLog("发送位置偏差_2;" + "offset_X:" + offset_X.ToString() + "offset_Y:" + offset_Y.ToString() + "offset_Phi:" + offset_Phi.ToString());
                                    //this.logRecord.WriteLog("发送位置偏差_2;" + "offset_X:" + offset_X.ToString() + "offset_Y:" + offset_Y.ToString() + "offset_Phi:" + offset_Phi.ToString());
                                    //角度差超出上限，当作异常信号     
                                    SendAndShowPhotoError(4, "位置偏差超出上限2！");             //先发上相机组装异常
                                    Thread.Sleep(50);
                                    SendAndShowPhotoError(3, "位置偏差超出上限2！");             //再发下相机组装异常
                                    angleRegulateNum = 0;
                                    upCamLocatDown2 = false;
                                }
                            }
                            catch (Exception ex)
                            {
                                SendAndShowPhotoError(4, "计算角度偏差出现异常_2！" + ex.Message);             //先发上相机组装异常
                                Thread.Sleep(50);
                                SendAndShowPhotoError(3, "计算角度偏差出现异常_2！" + ex.Message);             //再发下相机组装异常
                                angleRegulateNum = 0;
                            }
                            finally
                            {
                                AddFormLog("产品载具码:" + ShareData.strSNCode);
                                logRecord.WriteLog("产品载具码:" + ShareData.strSNCode);
                                //测试
                                //Task.Factory.StartNew(
                                //() =>
                                //{
                                SaveBitmap(ho_UpCam2, "UpCam", this.hWindow_upCam.HalconWindow);
                                SaveBitmap(downCamImage, "downCam", this.hWindow_downCam.HalconWindow);
                                SaveBitmap(codeImage, "Code", this.hWindow_scanCode.HalconWindow);
                                //});

                            }
                            #endregion
                        }
                    }
                    Thread.Sleep(50);
                }
                catch (Exception ex)
                {
                    AddFormLog("StartProcessDownCam下相机事件失败！" + ex.Message);
                    logRecord.WriteLog("StartProcessDownCam下相机事件失败！" + ex.Message);
                }
            }
        }
        private void StartProcessUpCam()
        {
            while (threadBusy)
            {
                try
                {
                    HObject ho_Image = null;
                    if (!upCamQueue.IsEmpty)
                    {
                        //从PLC获取SNCode
                        try
                        {
                            ShareData.strSNCode = "";
                            logRecord.WriteLog("清空SNCode" + ShareData.strSNCode);
                            this.tB_detectCTime.Text = ShareData.strSNCode;
                            //UPH-    Thread.Sleep(100);
                            ShareData.strSNCode = GetSNcodeFromPLC();
                            if (ShareData.strSNCode != null) ShareData.strSNCode = ShareData.strSNCode.Replace("\0", "");
                            AddFormLog("获取SN: " + ShareData.strSNCode);
                            logRecord.WriteLog("获取SN: " + ShareData.strSNCode);
                            this.tB_detectCTime.Text = ShareData.strSNCode;
                            //UPH-    Thread.Sleep(50);
                        }
                        catch (Exception exc)
                        {
                            AddFormLog("从PLC获取SN失败！" + exc.Message);
                            logRecord.WriteLog("从PLC获取SN失败！" + exc.Message);
                        }

                        bool nflag = upCamQueue.TryDequeue(out ho_Image);
                        if (!nflag || ho_Image == null) continue;
                        HTuple hv_ImageWidth, hv_ImageHeight;
                        HOperatorSet.GetImageSize(ho_Image, out hv_ImageWidth, out hv_ImageHeight);
                        if (upCamStatus == WorkStatus.上相机组装1)
                        {
                            #region 上相机定位1算法
                            HObject ho_fitCircleContour = null;
                            HObject ho_fitLine1Contour = null;
                            HObject ho_fitLine2Contour = null;
                            HObject ho_fitAngleLine = null;
                            HOperatorSet.GenEmptyObj(out ho_fitCircleContour);
                            HOperatorSet.GenEmptyObj(out ho_fitLine1Contour);
                            HOperatorSet.GenEmptyObj(out ho_fitLine2Contour);
                            HOperatorSet.GenEmptyObj(out ho_fitAngleLine);
                            try
                            {
                                double outRadius = 0;   //虚拟外围圆半径
                                if (upCamStatus == WorkStatus.上相机组装1)
                                    outRadius = ProjectInfo.Parameter.upCamLocateOutCircleRadius / ShareData.upCamPixSize1;
                                else   //组装2
                                    outRadius = ProjectInfo.Parameter.upCamLocateOutCircleRadius / ShareData.upCamPixSize2;
                                double circle_X = 0;
                                double circle_Y = 0;
                                double lineCorner_X = 0;
                                double lineCorner_Y = 0;
                                double angle = 0;
                                string bugInfo = "";
                                int countROI = 0;
                                //halconAlgorithm.ho_AdaptiveImage(this.hWindow_upCam, hv_ImageWidth, hv_ImageHeight);  //图像自适应
                                this.hWindow_upCam.HalconWindow.ClearWindow();
                                HOperatorSet.DispObj(ho_Image, this.hWindow_upCam.HalconWindow);
                                this.hWindow_upCam.SetFullImagePart();
                                halconAlgorithm.GetCoilPuckLocateROI(ho_Image, out upCamROI_circle);     //blob定位得到roi，替换原有roi
                                //if(true)
                                if (halconAlgorithm.GetPuckPosition(ho_Image, ProjectInfo.Parameter.upCamLocateFitCirclePara, ProjectInfo.Parameter.upCamLocateFitLine1Para, ProjectInfo.Parameter.upCamLocateFitLine2Para,
                                    upCamROI_circle, upCamROI_line1, upCamROI_line2, outRadius,
                                ProjectInfo.Parameter.upCamLocateSeekCornerStartPhi, ProjectInfo.Parameter.upCamLocateSeekCornerEndPhi, out ho_fitCircleContour, out ho_fitLine1Contour, out ho_fitLine2Contour,
                                out ho_fitAngleLine, out circle_X, out circle_Y, out lineCorner_X, out lineCorner_Y, out angle, out bugInfo))  //没有模板继承
                                {
                                    //显示图像及绘制的图形
                                    HOperatorSet.DispObj(ho_fitCircleContour, this.hWindow_upCam.HalconWindow);
                                    HOperatorSet.DispObj(ho_fitLine1Contour, this.hWindow_upCam.HalconWindow);
                                    HOperatorSet.DispObj(ho_fitLine2Contour, this.hWindow_upCam.HalconWindow);
                                    HOperatorSet.DispObj(ho_fitAngleLine, this.hWindow_upCam.HalconWindow);
                                    this.hWindow_upCam.SetFullImagePart();
                                    {
                                        upCamPos1_X = circle_X;
                                        upCamPos1_Y = circle_Y;
                                        upCamPos1_Phi = angle;
                                        channelQueue.Enqueue(1);                     //流道1
                                        //upCamLocatDown1 = true;
                                    }
                                    //UPH-     Thread.Sleep(80);
                                    SendPhotoDownSignal(3, 1);           //发送拍照完成信号
                                    this.logRecord.WriteLog("发送上相机定位1完成信号");
                                    AddFormLog("发送上相机定位1完成信号");
                                    HOperatorSet.GenEmptyObj(out ho_UpCam1);
                                    HOperatorSet.CopyImage(ho_Image, out ho_UpCam1);
                                }
                                else
                                {
                                    SendAndShowPhotoError(3, "上相机定位1异常" + bugInfo);
                                    //                                    Task.Factory.StartNew(
                                    //() =>
                                    //{

                                    SaveBitmapError(ho_Image, "UpCam_Error", this.hWindow_upCam.HalconWindow);
                                    logRecord.WriteLog("上相机定位异常图片保存！");
                                    //});
                                }
                            }
                            catch (Exception ex)
                            {
                                SendAndShowPhotoError(3, "上相机定位1异常" + ex.Message);
                                //                                Task.Factory.StartNew(
                                //() =>
                                //{

                                SaveBitmapError(ho_Image, "UpCam_Error", this.hWindow_upCam.HalconWindow);
                                logRecord.WriteLog("上相机定位异常图片保存！");
                                //});

                            }
                            finally
                            {
                                ho_fitCircleContour.Dispose();
                                ho_fitLine1Contour.Dispose();
                                ho_fitLine2Contour.Dispose();
                                ho_fitAngleLine.Dispose();



                                //Task.Factory.StartNew(
                                //    () =>
                                //    {
                                //        SaveBitmap(ho_Image, "UpCam", this.hWindow_upCam.HalconWindow);
                                //    });
                            }
                            #endregion
                            upCamStatus = WorkStatus.等待;
                        }

                        if (upCamStatus == WorkStatus.上相机组装2)
                        {
                            #region 上相机定位2算法
                            HObject ho_fitCircleContour = null;
                            HObject ho_fitLine1Contour = null;
                            HObject ho_fitLine2Contour = null;
                            HObject ho_fitAngleLine = null;
                            HOperatorSet.GenEmptyObj(out ho_fitCircleContour);
                            HOperatorSet.GenEmptyObj(out ho_fitLine1Contour);
                            HOperatorSet.GenEmptyObj(out ho_fitLine2Contour);
                            HOperatorSet.GenEmptyObj(out ho_fitAngleLine);
                            try
                            {
                                double outRadius = 0;   //虚拟外围圆半径
                                outRadius = ProjectInfo.Parameter.upCamLocateOutCircleRadius2 / ShareData.upCamPixSize2;

                                double circle_X = 0;
                                double circle_Y = 0;
                                double lineCorner_X = 0;
                                double lineCorner_Y = 0;
                                double angle = 0;
                                string bugInfo = "";
                                int countROI = 0;
                                //halconAlgorithm.ho_AdaptiveImage(this.hWindow_upCam, hv_ImageWidth, hv_ImageHeight);  //图像自适应
                                this.hWindow_upCam.HalconWindow.ClearWindow();
                                HOperatorSet.DispObj(ho_Image, this.hWindow_upCam.HalconWindow);
                                this.hWindow_upCam.SetFullImagePart();
                                halconAlgorithm.GetCoilPuckLocateROI(ho_Image, out upCamROI_circle);     //blob定位得到roi，替换原有roi
                                //if (true)
                                if (halconAlgorithm.GetPuckPosition(ho_Image, ProjectInfo.Parameter.upCamLocateFitCirclePara2, ProjectInfo.Parameter.upCamLocateFitLine1Para2, ProjectInfo.Parameter.upCamLocateFitLine2Para2,
                                    upCamROI_circle, upCamROI2_line1, upCamROI2_line2, outRadius,
                                ProjectInfo.Parameter.upCamLocateSeekCornerStartPhi2, ProjectInfo.Parameter.upCamLocateSeekCornerEndPhi2, out ho_fitCircleContour, out ho_fitLine1Contour, out ho_fitLine2Contour,
                                out ho_fitAngleLine, out circle_X, out circle_Y, out lineCorner_X, out lineCorner_Y, out angle, out bugInfo))  //没有模板继承
                                {
                                    //显示图像及绘制的图形
                                    HOperatorSet.DispObj(ho_fitCircleContour, this.hWindow_upCam.HalconWindow);
                                    HOperatorSet.DispObj(ho_fitLine1Contour, this.hWindow_upCam.HalconWindow);
                                    HOperatorSet.DispObj(ho_fitLine2Contour, this.hWindow_upCam.HalconWindow);
                                    HOperatorSet.DispObj(ho_fitAngleLine, this.hWindow_upCam.HalconWindow);
                                    this.hWindow_upCam.SetFullImagePart();
                                    {
                                        upCamPos2_X = circle_X;
                                        upCamPos2_Y = circle_Y;
                                        upCamPos2_Phi = angle;
                                        channelQueue.Enqueue(2);                     //流道2
                                        //upCamLocatDown2 = true;
                                    }
                                    //UPH-     Thread.Sleep(80);
                                    SendPhotoDownSignal(3, 1);           //发送拍照完成信号
                                    this.logRecord.WriteLog("发送上相机定位2完成信号");
                                    AddFormLog("发送上相机定位2完成信号");
                                    HOperatorSet.GenEmptyObj(out ho_UpCam2);
                                    HOperatorSet.CopyImage(ho_Image, out ho_UpCam2);
                                }
                                else
                                {
                                    SendAndShowPhotoError(3, "上相机定位2异常" + bugInfo);
                                    //                                    Task.Factory.StartNew(
                                    //() =>
                                    //{

                                    SaveBitmapError(ho_Image, "UpCam_Error", this.hWindow_upCam.HalconWindow);
                                    logRecord.WriteLog("上相机定位2图片保存！");
                                    //});
                                }
                            }
                            catch (Exception ex)
                            {
                                SendAndShowPhotoError(3, "上相机定位2异常" + ex.Message);
                                //                                Task.Factory.StartNew(
                                //() =>
                                //{

                                SaveBitmapError(ho_Image, "UpCam_Error", this.hWindow_upCam.HalconWindow);
                                logRecord.WriteLog("上相机定位2图片保存！");
                                //});
                            }
                            finally
                            {
                                ho_fitCircleContour.Dispose();
                                ho_fitLine1Contour.Dispose();
                                ho_fitLine2Contour.Dispose();
                                ho_fitAngleLine.Dispose();

                            }
                            #endregion

                            upCamStatus = WorkStatus.等待;
                        }
                    }
                    Thread.Sleep(50);
                }
                catch (Exception ex)
                {
                    AddFormLog("StartProcessUpCam上相机事件失败！" + ex.Message);
                    logRecord.WriteLog("StartProcessUpCam上相机事件失败！" + ex.Message);
                }
            }
        }
        private void StartProcessViewCam()
        {
            while (threadBusy)
            {
                try
                {
                    HObject ho_Image = null;
                    if (!detectCamQueue.IsEmpty)
                    {
                        bool nflag = detectCamQueue.TryDequeue(out ho_Image);
                        if (!nflag || ho_Image == null) continue;
                        HTuple hv_ImageWidth, hv_ImageHeight;
                        HOperatorSet.GetImageSize(ho_Image, out hv_ImageWidth, out hv_ImageHeight);
                        if (detectCamStatus == WorkStatus.机械手引导)
                        {
                            //halconAlgorithm.ho_AdaptiveImage(this.hWindowControl_guide, hv_ImageWidth, hv_ImageHeight);  //图像自适应
                            this.hWindowControl_guide.HalconWindow.ClearWindow();
                            this.Invoke(new Action(() =>
                            {
                                HOperatorSet.DispObj(ho_Image, this.hWindowControl_guide.HalconWindow);
                                this.hWindowControl_guide.SetFullImagePart();
                            }));
                            //changed by 07.12
                            //HOperatorSet.DispObj(ho_Image, this.hWindowControl_guide.HalconWindow);
                            HObject ho_circleContour = null;
                            HObject ho_Cross = null;
                            HObject ho_ROI = null;
                            try
                            {
                                HTuple hv_coor_Row = null;
                                HTuple hv_coor_Col = null;
                                HOperatorSet.GenEmptyObj(out ho_circleContour);
                                HOperatorSet.GenEmptyObj(out ho_Cross);
                                HOperatorSet.GenEmptyObj(out ho_ROI);
                                ho_circleContour.Dispose();
                                ho_ROI.Dispose();
                                //算法使用Blob定位后FittingCricle，下为参数设置
                                HTuple hv_cfgPara = new HTuple(250, 255, 50, 200, 1, 0, 1030, 940);//最小灰度，最大灰度，对比度，拟合点数量，sigma，从内向外0，ROI外圆半径，ROI内圆半径
                                halconAlgorithm.GetGuideMoveCoorFit(ho_Image, out ho_circleContour, out ho_ROI, hv_cfgPara, out hv_coor_Row, out hv_coor_Col);
                                // halconAlgorithm.GetGuideMoveCoor(ho_Image, out ho_circleContour, out hv_coor_Row, out hv_coor_Col);
                                if (hv_coor_Row > 0)
                                {
                                    HOperatorSet.SetColor(hWindowControl_guide.HalconWindow, "blue");
                                    HOperatorSet.DispObj(ho_circleContour, hWindowControl_guide.HalconWindow);
                                    ho_Cross.Dispose();
                                    HOperatorSet.GenCrossContourXld(out ho_Cross, hv_coor_Row, hv_coor_Col, 100, 0.785398);
                                    HOperatorSet.SetColor(hWindowControl_guide.HalconWindow, "red");
                                    HOperatorSet.DispObj(ho_Cross, hWindowControl_guide.HalconWindow);
                                    HOperatorSet.SetColor(hWindowControl_guide.HalconWindow, "yellow");
                                    HOperatorSet.DispObj(ho_ROI, hWindowControl_guide.HalconWindow);
                                    this.hWindowControl_guide.SetFullImagePart();
                                    int coor_X = (int)hv_coor_Col.D;
                                    int coor_Y = (int)hv_coor_Row.D;

                                    this.Invoke(new Action(() =>
                                    {
                                        this.tB_guide_X.Text = coor_X.ToString();
                                        this.tB_guide_Y.Text = coor_Y.ToString();
                                    }));
                                    RobotGuideJudgeProExist(1);          //发送有料信号，2代表无料,1代表有料
                                    Thread.Sleep(50);
                                    SendPhotoDownSignal(2, 1);           //发送拍照完成信号                               
                                    Thread.Sleep(50);
                                    SetRobotGuideCoor(coor_X, coor_Y);   //发送机械手引导坐标，单位像素
                                    Thread.Sleep(50);
                                    NoticeRobotGuideMoveSignal(1);       //通知机械手走位信号
                                    this.logRecord.WriteLog("发送机械走位信号！" + coor_X.ToString() + "," + coor_Y.ToString());
                                    AddFormLog("发送机械走位信号！" + coor_X.ToString() + "," + coor_Y.ToString());
                                    //                                    Task.Factory.StartNew(
                                    //() =>
                                    //{
                                    SaveBitmap(ho_Image, "Guide", this.hWindowControl_guide.HalconWindow);
                                    //});

                                }
                                else
                                {
                                    RobotGuideJudgeProExist(2);          //发送有料信号，2代表无料，1代表有料
                                    Thread.Sleep(50);
                                    SendPhotoDownSignal(2, 1);           //发送拍照完成信号
                                    this.logRecord.WriteLog("发送无料信号！");
                                    AddFormLog("发送无料信号！");
                                    //                                    Task.Factory.StartNew(
                                    //() =>
                                    //{
                                    SaveBitmapError(ho_Image, "Guide_Error", this.hWindowControl_guide.HalconWindow);
                                    logRecord.WriteLog("引导相机定位异常图片保存！");
                                    //});

                                }
                            }
                            catch (Exception ex)
                            {
                                SendAndShowPhotoError(2, "机械手引导异常！" + ex.Message);
                                logRecord.WriteLog("机械手引导异常！" + ex.Message);
                                //                                Task.Factory.StartNew(
                                //() =>
                                //{
                                SaveBitmapError(ho_Image, "Guide_Error", this.hWindowControl_guide.HalconWindow);
                                logRecord.WriteLog("引导相机定位异常图片保存！");
                                //});
                            }
                            finally
                            {
                                ho_circleContour.Dispose();
                                ho_Cross.Dispose();
                            }
                        }
                    }
                    Thread.Sleep(50);

                }
                catch (Exception ex)
                {
                    AddFormLog("引导相机事件失败！" + ex.Message);
                    logRecord.WriteLog("StartProcessReviewCam引导相机事件失败！" + ex.Message);
                }
            }
        }
        private void SendAndShowPhotoError(int errorIndex, string bugInfo)
        {
            //异常处理：
            //1为引导处理异常
            //2为下相机组装异常
            //4为上相机组装异常
            //8为撕膜检测异常
            //16为读码异常         
            SendPhotoDownSignal(errorIndex, 2);
            //UPH-    Thread.Sleep(50);
            // SendPCErrorSignal(errorIndex);           //PC异常信号
            this.logRecord.WriteLog(bugInfo);
            AddFormLog(bugInfo);
            Invoke(this.dGSetStateShow, "Error", Color.DarkOrange);
        }
        private void SaveBitmap(HObject ho_Image, string saveLable, HTuple hv_WindowHandle)
        {
            try
            {
                if (ho_Image!=null)
                {
                    if (ProjectInfo.Parameter.saveImageType == 1)
                    {
                        string saveFold = "";
                        if (saveLable == "Guide")
                        {
                            saveFold = Path.Combine(ProjectInfo.Parameter.saveImagePath, DateTime.Now.ToString("yyyyMMdd"), "GuideImages");
                        }
                        else
                        {
                            if (ShareData.strSNCode != "")
                            {
                                saveFold = Path.Combine(ProjectInfo.Parameter.saveImagePath, DateTime.Now.ToString("yyyyMMdd"), ShareData.strSNCode);
                            }
                            else
                            {
                                ShareData.strSNCode = DateTime.Now.ToString("yyyyMMddHHMMSS");
                                saveFold = Path.Combine(ProjectInfo.Parameter.saveImagePath, DateTime.Now.ToString("yyyyMMdd"), ShareData.strSNCode);
                            }
                        }
                        if (!Directory.Exists(saveFold)) Directory.CreateDirectory(saveFold);   //创建文件夹
                        saveImageInfo saveImage = new saveImageInfo();
                        saveImage.saveImage = ho_Image.Clone();
                        saveImage.saveFormat = ProjectInfo.Parameter.saveImageFormat;

                        //if (saveLable == "Code")
                        //{
                        //    if (ShareData.strCoilCode == "")
                        //    {
                        //        saveImage.savePath = string.Format("{0}\\{1}_{2}", saveFold, saveLable, DateTime.Now.ToString("HHmmss"));
                        //    }
                        //    else
                        //    {
                        //        saveImage.savePath = string.Format("{0}\\{1}_{2}", saveFold, saveLable, ShareData.strCoilCode);
                        //    }
                        //}
                        //else
                        //{
                        saveImage.savePath = string.Format("{0}\\{1}_{2}", saveFold, saveLable, DateTime.Now.ToString("HHmmss"));
                        //}
                        saveQueue.Enqueue(saveImage);
                    }
                    if (ProjectInfo.Parameter.isSaveDetectImage)  //保存检测图
                    {
                        string saveFold = Path.Combine(ProjectInfo.Parameter.saveImagePath, DateTime.Now.ToString("yyyyMMdd"), SNCode);
                        if (!Directory.Exists(saveFold)) Directory.CreateDirectory(saveFold);   //创建文件夹
                        HObject ho_img = null;
                        HOperatorSet.DumpWindowImage(out ho_img, hv_WindowHandle);
                        saveImageInfo saveImage = new saveImageInfo();
                        saveImage.saveImage = ho_img;
                        saveImage.saveFormat = 1;          //检测效果图默认保存为jpg格式
                        saveImage.savePath = string.Format("{0}\\{1}_detect_{2}", saveFold, saveLable, DateTime.Now.ToString("HHmmss"));
                        saveQueue.Enqueue(saveImage);
                    }
                }
               

            }
            catch (Exception exc)
            {
                AddFormLog("SaveBitmap保存图片方法失败！" + exc.Message);
                logRecord.WriteLog("SaveBitmap保存图片方法失败！" + exc.Message);
            }
        }
        private void SaveBitmapError(HObject ho_Image, string saveLable, HTuple hv_WindowHandle)
        {
            try
            {
                if (ProjectInfo.Parameter.saveImageType == 1)
                {
                    string saveFold = "";
                    if (ShareData.strSNCode != "")
                    {
                        saveFold = Path.Combine(ProjectInfo.Parameter.saveImagePath, DateTime.Now.ToString("yyyyMMdd"), "ErrorImages");
                    }
                    else
                    {
                        ShareData.strSNCode = DateTime.Now.ToString("yyyyMMddHHMMSS");
                        saveFold = Path.Combine(ProjectInfo.Parameter.saveImagePath, DateTime.Now.ToString("yyyyMMdd"), "ErrorImages");
                    }

                    if (!Directory.Exists(saveFold)) Directory.CreateDirectory(saveFold);   //创建文件夹
                    saveImageInfo saveImage = new saveImageInfo();
                    saveImage.saveImage = ho_Image.Clone();
                    saveImage.saveFormat = ProjectInfo.Parameter.saveImageFormat;

                    //if (saveLable.Contains("Code"))
                    //{
                    //    if (ShareData.strCoilCode == "")
                    //    {
                    //        saveImage.savePath = string.Format("{0}\\{1}_{2}", saveFold, saveLable, DateTime.Now.ToString("HHmmss"));
                    //    }
                    //    else
                    //    {
                    //        saveImage.savePath = string.Format("{0}\\{1}_{2}", saveFold, saveLable, ShareData.strCoilCode + "_" + DateTime.Now.ToString("HHmmss"));
                    //    }
                    //}
                    //else if (saveLable.Contains("UpCam"))
                    //{
                    //    if (ShareData.strSNCode == "")
                    //    {
                    //        saveImage.savePath = string.Format("{0}\\{1}_{2}", saveFold, saveLable, DateTime.Now.ToString("HHmmss"));
                    //    }
                        //else
                        //{
                        //    saveImage.savePath = string.Format("{0}\\{1}_{2}", saveFold, saveLable, ShareData.strSNCode + "_" + DateTime.Now.ToString("HHmmss"));
                        //}
                    //}
                    //else
                    //{
                        saveImage.savePath = string.Format("{0}\\{1}_{2}", saveFold, saveLable, DateTime.Now.ToString("HHmmss"));
                    //}
                    saveQueue.Enqueue(saveImage);
                }
                if (ProjectInfo.Parameter.isSaveDetectImage)  //保存检测图
                {
                    string saveFold = Path.Combine(ProjectInfo.Parameter.saveImagePath, DateTime.Now.ToString("yyyyMMdd"), SNCode);
                    if (!Directory.Exists(saveFold)) Directory.CreateDirectory(saveFold);   //创建文件夹
                    HObject ho_img = null;
                    HOperatorSet.DumpWindowImage(out ho_img, hv_WindowHandle);
                    saveImageInfo saveImage = new saveImageInfo();
                    saveImage.saveImage = ho_img;
                    saveImage.saveFormat = 1;          //检测效果图默认保存为jpg格式
                    saveImage.savePath = string.Format("{0}\\{1}_detect_{2}", saveFold, saveLable, DateTime.Now.ToString("HHmmss"));
                    saveQueue.Enqueue(saveImage);
                }

            }
            catch (Exception exc)
            {
                AddFormLog("SaveBitmap保存图片方法失败！" + exc.Message);
                logRecord.WriteLog("SaveBitmap保存图片方法失败！" + exc.Message);
            }
        }
        public string getTime()
        {
            DateTime dt = DateTime.Now;
            return dt.Year.ToString().PadLeft(4, '0') + dt.Month.ToString().PadLeft(2, '0') + dt.Day.ToString().PadLeft(2, '0')
                + dt.Hour.ToString().PadLeft(2, '0') + dt.Minute.ToString().PadLeft(2, '0') + dt.Second.ToString().PadLeft(2, '0');
        }
        private void StartSaveImage()
        {
            while (threadBusy)
            {
                try
                {
                    DriveInfo[] diList = DriveInfo.GetDrives();
                    saveImageInfo saveImage = new saveImageInfo();
                    if (!saveQueue.IsEmpty)
                    {
                        saveQueue.TryDequeue(out saveImage);

                        if (saveImage == null)
                        {
                            Thread.Sleep(20);
                            continue;
                        }
                        switch (saveImage.saveFormat)
                        {
                            case 0:
                                if (saveImage.saveImage != null)
                                    HOperatorSet.WriteImage(saveImage.saveImage, "bmp", 0, saveImage.savePath + ".bmp");
                                break;
                            case 1:
                                if (saveImage.saveImage != null)
                                    HOperatorSet.WriteImage(saveImage.saveImage, "jpeg", 0, saveImage.savePath + ".jpg");
                                break;
                            case 2:
                                if (saveImage.saveImage != null)
                                    HOperatorSet.WriteImage(saveImage.saveImage, "png", 0, saveImage.savePath + ".png");
                                break;
                        }
                        // if (saveImage.saveImage != null)
                        // saveImage.saveImage.Dispose();
                    }
                    string[] slist = Directory.GetCurrentDirectory().Split('\\');
                    foreach (DriveInfo di in diList)
                    {
                        if (di.Name.Contains(slist[0]) && di.AvailableFreeSpace / 1024 / 1024 / 1024 < 1)
                        {
                            MessageBox.Show(slist[0] + " 磁盘空间不足1GB");
                        }
                    }
                    //UPH-     Thread.Sleep(200);
                    Thread.Sleep(100);
                }
                catch (Exception exc)
                {
                    AddFormLog("StartSaveImage 开始存图线程失败!" + exc.Message);
                    logRecord.WriteLog("StartSaveImage 开始存图线程失败!" + exc.Message);
                }
            }

        }
        public string Transformation(double Value)//-1234.5678 处理
        {
            string strTemp1 = Value.ToString("f4"); //添加小数点后4位数
            int strLength = strTemp1.Length;
            int Index1 = strTemp1.IndexOf(".");
            string strLeft = strTemp1.Substring(0, Index1).PadLeft(5);//截取小数点前面的字符并补齐到5位，不够补空格
            string strRight = strTemp1.Substring(Index1);//截取小数点及后面的字符
            return strLeft + strRight;//字符叠加
        }

        //private void RequestPhotoSignal()
        //{
        //    while (threadBusy)
        //    {
        //        lock (lockSignal)
        //        {
        //            RequestPhotoSignal();   //请求拍照信号   
        //        }
        //        Thread.Sleep(100);
        //    }
        //}

        #endregion

        #region 统计数据
        private void InitialProStatis()
        {
            try
            {
                this.cIniFactory = new CINIFactory(System.Environment.CurrentDirectory + "\\", "statis");    //加载统计数据
                proTotalNum = int.Parse(cIniFactory.ReadIniData("data", "totalNum", ""));
                proOkNum = int.Parse(cIniFactory.ReadIniData("data", "OKNum", ""));
                proOkRatio = double.Parse(cIniFactory.ReadIniData("data", "OKRatio", ""));
            }
            catch (Exception ex)
            {
                MessageBox.Show("获取统计数据失败！");
            }
        }
        public void SaveProStatis()
        {
            if (ProjectInfo.Parameter == null) return;

            if (this.cIniFactory != null)
            {
                this.cIniFactory.WriteIniData("data", "totalNum", proTotalNum.ToString());
                this.cIniFactory.WriteIniData("data", "OKNum", proOkNum.ToString());
                this.cIniFactory.WriteIniData("data", "OKRatio", proOkRatio.ToString("f2"));
            }
        }
        private void btn_clearData_Click(object sender, EventArgs e)
        {
            proTotalNum = 0;
            proOkNum = 0;
            proOkRatio = 0;
            this.tB_proTotalNum.Text = "0";
            this.tB_proOKNum.Text = "0";
            this.tB_proOkRatio.Text = "0";
            this.lbMsg.Items.Clear();    //清空列表
        }
        #endregion

        #region 开始与停止检测
        private void ts_StartDetct_Click(object sender, EventArgs e)
        {
            start();
        }

        private void start()
        {
            try
            {
                bool flag = ShareData.tcpMitsubishiTCP.Connect(ProjectInfo.Parameter.tcpIpAddress, ProjectInfo.Parameter.tcpPort.ToString());      //连接server  
                if (!flag)
                {
                    MessageBox.Show("通讯连接失败！");
                    AddFormLog("通讯连接失败!", Color.Red);
                    return;
                }
            }
            catch (Exception exc)
            {
                MessageBox.Show("通讯连接失败！");
                AddFormLog("通讯连接失败!", Color.Red);
                return;
            }
            AddFormLog("通讯连接成功!");
            logRecord.WriteLog("通讯连接成功!");
            if (!InitialCameral()) return;      //加载相机
            if (!LoadMatchModel()) return;      //加载模型
            if (!LoadDetectRegion()) return;    //加载region
            if (!LoadTransMetric()) return;     //加载仿射转换矩阵
            downCamLocatDown = false;
            upCamLocatDown1 = false;
            upCamLocatDown2 = false;

            threadBusy = true;
            angleRotateOK = false;
            angleRegulateNum = 0;
            while (!channelQueue.IsEmpty)   //清空队列
            {
                int mChannel = -1;
                channelQueue.TryDequeue(out mChannel);
            }
            downCamStatus = WorkStatus.等待;
            upCamStatus = WorkStatus.等待;
            detectCamStatus = WorkStatus.等待;
            StartThread();     //开启线程
            this.ts_StartDetct.Enabled = false;
            this.ts_cameraSet.Enabled = false;
            this.ts_calibration.Enabled = false;
            this.ts_SetParaForm.Enabled = false;
            this.ts_StopDetect.Enabled = true;

            StartPlc();

            SendPCReadySignal(1);

            AddFormLog("开启检测!", Color.Yellow);
        }
        private void ts_StopDetect_Click(object sender, EventArgs e)
        {
            threadBusy = false;
            SendPCReadySignal(0);        //关闭pc准备信号
            for (int i = 0; i < ShareData.cameralOpenList.Count; i++)    //关闭已经打开的相机
            {
                ShareData.MvsCameral.StopHKCamGrab(i);    //停止采集
                ShareData.MvsCameral.DestroyHKCam(i);     //关闭设备
            }

            if (this.proDownCamThread != null)          //关闭线程
            {
                this.proDownCamThread.Abort();
                this.proDownCamThread = null;
            }
            if (this.proUpCamThread != null)          //关闭线程
            {
                this.proUpCamThread.Abort();
                this.proUpCamThread = null;
            }
            if (this.proViewCamThread != null)          //关闭线程
            {
                this.proViewCamThread.Abort();
                this.proViewCamThread = null;
            }
            if (this.SaveImageThread != null)
            {
                this.SaveImageThread.Abort();          //停机存图信号
                this.SaveImageThread = null;
            }
            while (!downCamQueue.IsEmpty)             //清空队列
            {
                HObject bmp = null;
                downCamQueue.TryDequeue(out bmp);
            }
            while (!upCamQueue.IsEmpty)             //清空队列
            {
                HObject bmp = null;
                upCamQueue.TryDequeue(out bmp);
            }
            ClearMatchModel();                                     //清除模板

            StopPlc();

            ShareData.tcpMitsubishiTCP.DisConnect();  //关闭socket通讯连接

            this.ts_StartDetct.Enabled = true;
            this.ts_cameraSet.Enabled = true;
            this.ts_calibration.Enabled = true;
            this.ts_SetParaForm.Enabled = true;
            this.ts_StopDetect.Enabled = false;
            AddFormLog("停止检测!", Color.LightGray);
        }
        private void StartThread()
        {
            //根据项目不同选择不同的检测线程
            //if (ShareData.projectItem != ShareData.ItemType.手动线组装)
            //{
            //this.requestPhotoThread = new Thread(RequestPhotoSignal);   //暂时按照字符串的形式
            //this.requestPhotoThread.IsBackground = true;
            //this.requestPhotoThread.Start();
            //}
            //if (ShareData.projectItem == ShareData.ItemType.手动线组装 || ShareData.projectItem == ShareData.ItemType.coil半自动线
            //    || ShareData.projectItem == ShareData.ItemType.自动线coil组装 || ShareData.projectItem == ShareData.ItemType.自动线spring组装)
            //{
            this.proDownCamThread = new Thread(StartProcessDownCam);
            this.proDownCamThread.IsBackground = true;
            this.proDownCamThread.Start();

            this.proUpCamThread = new Thread(StartProcessUpCam);
            this.proUpCamThread.IsBackground = true;
            this.proUpCamThread.Start();
            // }
            //if (ShareData.projectItem == ShareData.ItemType.手动线组装 || ShareData.projectItem == ShareData.ItemType.coil半自动线 || ShareData.projectItem == ShareData.ItemType.coil胶形检测
            //    || ShareData.projectItem == ShareData.ItemType.coil自检 || ShareData.projectItem == ShareData.ItemType.spring胶形检测 || ShareData.projectItem == ShareData.ItemType.spring自检)
            //{
            this.proViewCamThread = new Thread(StartProcessViewCam);
            this.proViewCamThread.IsBackground = true;
            this.proViewCamThread.Start();
            //}
            this.SaveImageThread = new Thread(StartSaveImage);
            this.SaveImageThread.IsBackground = true;
            this.SaveImageThread.Start();
        }
        private bool InitialCameral()
        {
            try
            {
                ShareData.cameralOpenList.Clear();
                List<string> deviceInfo = new List<string>();
                if (ShareData.MvsCameral.CameralDeviceListAcq(out deviceInfo))          //初始化设备，可以重复初始化设备,可以预防工程建好后重新加入相机
                {
                    if (deviceInfo.Count > 0)
                    {
                        for (int i = 0; i < deviceInfo.Count; i++)
                        {
                            if (!ShareData.MvsCameral.OpenDevice(i))               //打开设备
                            {
                                MessageBox.Show("打开相机失败！");
                                return false;
                            }
                            if (ShareData.MvsCameral.StartHKCamGrab(i) != 0)      //开始采集
                            {
                                MessageBox.Show("打开相机失败");
                                return false;
                            }
                            ShareData.MvsCameral.SetTriggerGrab(i);   //设置为触发模式
                            ShareData.MvsCameral.SetSoftTrigger(i);   //设置为软触发模式
                            ShareData.cameralOpenList.Add(i);
                        }
                        //设置胶形检测相机参数,涉及到1个相机
                        if (ShareData.projectItem == ShareData.ItemType.spring胶形检测 || ShareData.projectItem == ShareData.ItemType.coil胶形检测)
                        {
                            if (ProjectInfo.Parameter.glueCamIndex < 0 || ProjectInfo.Parameter.glueCamIndex > deviceInfo.Count - 1)
                            {
                                MessageBox.Show("请先进行相机设置！");
                                return false;
                            }
                            ShareData.MvsCameral.SetHKCamExposure(ProjectInfo.Parameter.glueCamIndex, ProjectInfo.Parameter.glueCamExposure);   //设置曝光
                            ShareData.MvsCameral.SetHKCamExposure(ProjectInfo.Parameter.glueCamIndex, ProjectInfo.Parameter.glueCamGain);       //设置增益
                        }
                        //设置自检相机参数，涉及1个相机
                        if (ShareData.projectItem == ShareData.ItemType.spring自检 || ShareData.projectItem == ShareData.ItemType.coil自检)
                        {
                            if (ProjectInfo.Parameter.reviewCamIndex < 0 || ProjectInfo.Parameter.reviewCamIndex > deviceInfo.Count - 1)
                            {
                                MessageBox.Show("请先进行相机设置！");
                                return false;
                            }
                            ShareData.MvsCameral.SetHKCamExposure(ProjectInfo.Parameter.reviewCamIndex, ProjectInfo.Parameter.reviewCamExposure1);   //设置曝光1
                            ShareData.MvsCameral.SetHKCamExposure(ProjectInfo.Parameter.reviewCamIndex, ProjectInfo.Parameter.reviewCamGain1);       //设置增益1
                        }
                        //设置自动线组装相机参数,涉及到上、下、引导三个相机
                        if (ShareData.projectItem == ShareData.ItemType.自动线spring组装 || ShareData.projectItem == ShareData.ItemType.自动线coil组装)
                        {
                            if (ProjectInfo.Parameter.downCamIndex < 0 || ProjectInfo.Parameter.upCamIndex < 0 || ProjectInfo.Parameter.guideCamIndex < 0
                                || ProjectInfo.Parameter.downCamIndex > deviceInfo.Count - 1 || ProjectInfo.Parameter.upCamIndex > deviceInfo.Count - 1 || ProjectInfo.Parameter.guideCamIndex > deviceInfo.Count - 1)
                            {
                                MessageBox.Show("请先进行相机设置");
                                return false;
                            }
                            ShareData.MvsCameral.SetHKCamExposure(ProjectInfo.Parameter.guideCamIndex, ProjectInfo.Parameter.guideCamExposure);   //设置曝光
                            ShareData.MvsCameral.SetHKCamExposure(ProjectInfo.Parameter.guideCamIndex, ProjectInfo.Parameter.guideCamGain);       //设置增益
                            ShareData.MvsCameral.SetHKCamExposure(ProjectInfo.Parameter.downCamIndex, ProjectInfo.Parameter.downCamExposure);     //设置曝光
                            ShareData.MvsCameral.SetHKCamExposure(ProjectInfo.Parameter.downCamIndex, ProjectInfo.Parameter.downCamGain);         //设置曝光
                            ShareData.MvsCameral.SetHKCamExposure(ProjectInfo.Parameter.upCamIndex, ProjectInfo.Parameter.upCamExposure1);         //设置曝光                    
                            ShareData.MvsCameral.SetHKCamExposure(ProjectInfo.Parameter.upCamIndex, ProjectInfo.Parameter.upCamGain1);             //设置曝光
                        }
                        //设置手动线组装和coil半自动线相机参数,涉及到上、下、自检三个相机
                        if (ShareData.projectItem == ShareData.ItemType.手动线组装 || ShareData.projectItem == ShareData.ItemType.coil半自动线)
                        {
                            if (ProjectInfo.Parameter.downCamIndex < 0 || ProjectInfo.Parameter.upCamIndex < 0 || ProjectInfo.Parameter.reviewCamIndex < 0
                                || ProjectInfo.Parameter.downCamIndex > deviceInfo.Count - 1 || ProjectInfo.Parameter.upCamIndex > deviceInfo.Count - 1 || ProjectInfo.Parameter.reviewCamIndex > deviceInfo.Count - 1)
                            {
                                MessageBox.Show("请先进行相机设置");
                                return false;
                            }
                            ShareData.MvsCameral.SetHKCamExposure(ProjectInfo.Parameter.reviewCamIndex, ProjectInfo.Parameter.reviewCamExposure1);   //设置曝光
                            ShareData.MvsCameral.SetHKCamExposure(ProjectInfo.Parameter.reviewCamIndex, ProjectInfo.Parameter.reviewCamGain1);       //设置增益
                            ShareData.MvsCameral.SetHKCamExposure(ProjectInfo.Parameter.downCamIndex, ProjectInfo.Parameter.downCamExposure);     //设置曝光
                            ShareData.MvsCameral.SetHKCamExposure(ProjectInfo.Parameter.downCamIndex, ProjectInfo.Parameter.downCamGain);         //设置曝光
                            ShareData.MvsCameral.SetHKCamExposure(ProjectInfo.Parameter.upCamIndex, ProjectInfo.Parameter.upCamExposure1);         //设置曝光                    
                            ShareData.MvsCameral.SetHKCamExposure(ProjectInfo.Parameter.upCamIndex, ProjectInfo.Parameter.upCamGain1);             //设置曝光
                        }
                    }
                    else
                    {
                        MessageBox.Show("查找到相机的数量为0");
                        return false;
                    }
                }
                else
                {
                    MessageBox.Show("初始化相机失败！");
                    return false;
                }
                return true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return false;
            }
        }
        private bool LoadTransMetric()
        {
            try
            {
                string filePath = Path.Combine(System.Environment.CurrentDirectory, "trans") + "//downCam.resx";
                if (File.Exists(filePath))
                    HOperatorSet.ReadTuple(filePath, out downCamHomMat2D);
                else
                {
                    MessageBox.Show("下相机放射矩阵为空！");
                    return false;
                }
                filePath = Path.Combine(System.Environment.CurrentDirectory, "trans") + "//upCam1.resx";
                if (File.Exists(filePath))
                    HOperatorSet.ReadTuple(filePath, out upCam1HomMat2D);
                else
                {
                    MessageBox.Show("上相机流道1放射矩阵为空！");
                    return false;
                }
                filePath = Path.Combine(System.Environment.CurrentDirectory, "trans") + "//upCam2.resx";
                if (File.Exists(filePath))
                    HOperatorSet.ReadTuple(filePath, out upCam2HomMat2D);
                else
                {
                    MessageBox.Show("上相机流道2放射矩阵为空！");
                    return false;
                }
                return true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return false;
            }
        }
        private bool LoadDetectRegion()
        {
            try
            {
                string upCircleFile = Path.Combine(System.Environment.CurrentDirectory, "region", "upCam") + "//circle.hobj";
                if (File.Exists(upCircleFile)) upCamROI_circle.ReadObject(upCircleFile);           //读取roi
                else
                {
                    MessageBox.Show("上相机circleRegion为空！");
                    return false;
                }
                string upLine1File = Path.Combine(System.Environment.CurrentDirectory, "region", "upCam") + "//line1.hobj";
                if (File.Exists(upLine1File)) upCamROI_line1.ReadObject(upLine1File);           //读取roi
                else
                {
                    MessageBox.Show("上相机line1Region为空！");
                    return false;
                }
                string upLine2File = Path.Combine(System.Environment.CurrentDirectory, "region", "upCam") + "//line2.hobj";
                if (File.Exists(upLine2File)) upCamROI_line2.ReadObject(upLine2File);           //读取roi
                else
                {
                    MessageBox.Show("上相机line2Region为空！");
                    return false;
                }

                string upCircleFile2 = Path.Combine(System.Environment.CurrentDirectory, "region", "upCam2") + "//circle.hobj";
                if (File.Exists(upCircleFile2)) upCamROI2_circle.ReadObject(upCircleFile2);           //读取roi
                else
                {
                    MessageBox.Show("上相机circleRegion为空！");
                    return false;
                }
                string upLine1File2 = Path.Combine(System.Environment.CurrentDirectory, "region", "upCam2") + "//line1.hobj";
                if (File.Exists(upLine1File2)) upCamROI2_line1.ReadObject(upLine1File2);           //读取roi
                else
                {
                    MessageBox.Show("上相机line1Region为空！");
                    return false;
                }
                string upLine2File2 = Path.Combine(System.Environment.CurrentDirectory, "region", "upCam2") + "//line2.hobj";
                if (File.Exists(upLine2File2)) upCamROI2_line2.ReadObject(upLine2File2);           //读取roi
                else
                {
                    MessageBox.Show("上相机line2Region为空！");
                    return false;
                }
                string downCircleFile = Path.Combine(System.Environment.CurrentDirectory, "region", "downCam") + "//circle.hobj";
                if (File.Exists(downCircleFile)) downCamROI_circle.ReadObject(downCircleFile);           //读取roi
                else
                {
                    MessageBox.Show("下相机circleRegion为空！");
                    return false;
                }
                string downLine1File = Path.Combine(System.Environment.CurrentDirectory, "region", "downCam") + "//line1.hobj";
                if (File.Exists(downLine1File)) downCamROI_line1.ReadObject(downLine1File);           //读取roi
                else
                {
                    MessageBox.Show("下相机line1Region为空！");
                    return false;
                }
                string downLine2File = Path.Combine(System.Environment.CurrentDirectory, "region", "downCam") + "//line2.hobj";
                if (File.Exists(downLine2File)) downCamROI_line2.ReadObject(downLine2File);           //读取roi
                else
                {
                    MessageBox.Show("下相机line2Region为空！");
                    return false;
                }
                return true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return false;
            }
        }
        private bool LoadMatchModel()
        {
            //加载模板
            try
            {
                //复检1模板匹配
                if (ShareData.projectItem == ShareData.ItemType.自动线coil组装 || ShareData.projectItem == ShareData.ItemType.coil半自动线)
                {
                    string modelImageFold = Path.Combine(System.Environment.CurrentDirectory, "model", "downCamLocate");
                    if (ProjectInfo.Parameter.downCamLocateMatchPara.modelMatchType == 0)   //基于形状
                    {
                        string shapeModelFile = modelImageFold + "\\model.shm";
                        if (!File.Exists(shapeModelFile))
                        {
                            MessageBox.Show("模板文件不存在，请先加载模型！");
                            return false;
                        }
                        HOperatorSet.ReadShapeModel(shapeModelFile, out hv_downCamModel);  //加载模板
                    }
                    else if (ProjectInfo.Parameter.downCamLocateMatchPara.modelMatchType == 1)  //基于灰度
                    {
                        string nccModelFile = modelImageFold + "\\model.ncm";
                        if (!File.Exists(nccModelFile))
                        {
                            MessageBox.Show("模板文件不存在，请先加载模型！");
                            return false;
                        }
                        HOperatorSet.ReadNccModel(nccModelFile, out hv_downCamModel);  //加载模板
                    }
                    isLoadDownCamModel = true;
                }
                return true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return false;
            }
        }
        private void ClearMatchModel()
        {
            //清除模板
            if (isLoadDownCamModel)
            {
                if (ProjectInfo.Parameter.downCamLocateMatchPara.modelMatchType == 0)   //基于形状
                {
                    HOperatorSet.ClearShapeModel(hv_downCamModel);                     //清除模板
                }
                else if (ProjectInfo.Parameter.downCamLocateMatchPara.modelMatchType == 1)  //基于灰度
                {
                    HOperatorSet.ClearNccModel(hv_downCamModel);                   //清除模板
                }
                isLoadDownCamModel = false;
            }
            if (isLoadUpCamModel)
            {
                if (ProjectInfo.Parameter.upCamLocateMatchPara.modelMatchType == 0)   //基于形状
                {
                    HOperatorSet.ClearShapeModel(hv_upCamModel);                     //清除模板
                }
                else if (ProjectInfo.Parameter.upCamLocateMatchPara.modelMatchType == 1)  //基于灰度
                {
                    HOperatorSet.ClearNccModel(hv_upCamModel);                   //清除模板
                }
                isLoadUpCamModel = false;
            }
            if (isLoadReviewModel)
            {
                if (ProjectInfo.Parameter.reviewLowMatchPara.modelMatchType == 0)   //基于形状
                {
                    HOperatorSet.ClearShapeModel(hv_reviewModel);                     //清除模板
                }
                else if (ProjectInfo.Parameter.reviewLowMatchPara.modelMatchType == 1)  //基于灰度
                {
                    HOperatorSet.ClearNccModel(hv_reviewModel);                   //清除模板
                }
                isLoadReviewModel = false;
            }
            if (isLoadReview1Model)
            {
                if (ProjectInfo.Parameter.reviewLowMatchPara.modelMatchType == 0)   //基于形状
                {
                    HOperatorSet.ClearShapeModel(hv_coilreview1Model);                     //清除模板
                }
                else if (ProjectInfo.Parameter.reviewLowMatchPara.modelMatchType == 1)  //基于灰度
                {
                    HOperatorSet.ClearNccModel(hv_coilreview1Model);                   //清除模板
                }
                isLoadReview1Model = false;
            }
        }
        #endregion

        #region 窗体打开设置
        private void MainForm_Load(object sender, EventArgs e)
        {
            //if (!this.tB_SNcode.Focused)
            //{
            //    this.tB_SNcode.Focus();
            //    this.tB_SNcode.SelectAll();
            //}
            AddFormLog(DMConnectStatus, DMConnectStatus.Contains("失败") ? Color.Red : SystemColors.Window);

            //ts_StartDetct.PerformClick();
            //start();
        }
        private void ts_SetParaForm_Click(object sender, EventArgs e)
        {
            //打开参数设置窗体
            SetParaForm setParaForm = new SetParaForm();
            setParaForm.ShowDialog();
        }
        private void ts_calibration_Click(object sender, EventArgs e)
        {
            //打开标定窗体
            ShareData.MvsCameral.captureImage -= MvsCameral_captureImage;
            CalibForm calibForm = new CalibForm();
            calibForm.ShowDialog();
            ShareData.MvsCameral.captureImage += MvsCameral_captureImage;
        }
        private void ts_cameraSet_Click(object sender, EventArgs e)
        {
            //打开相机设置窗体
            ShareData.MvsCameral.captureImage -= MvsCameral_captureImage;
            MVSCamera mvsCameraForm = new MVSCamera();
            mvsCameraForm.ShowDialog();
            ShareData.MvsCameral.captureImage += MvsCameral_captureImage;
        }
        private void ts_CloseWindow_Click(object sender, EventArgs e)
        {
            DialogResult dr = MessageBox.Show("是否确认关闭窗体？", "关闭窗体", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
            if (dr == DialogResult.OK)
            {
                ts_StopDetect.PerformClick();

                if (ShareData.tcpMitsubishiTCP.melsec_net != null)              //关闭tcp连接
                {
                    SendPCReadySignal(0);        //关闭pc准备信号
                    ShareData.tcpMitsubishiTCP.DisConnect();
                }
                for (int i = 0; i < ShareData.cameralOpenList.Count; i++)    //关闭已经打开的相机
                {
                    ShareData.MvsCameral.StopHKCamGrab(i);    //停止采集
                    ShareData.MvsCameral.DestroyHKCam(i);     //关闭设备
                }
                SaveProStatis();                              //保存统计数据
                this.Close();
            }
        }
        private void 管理员ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AdminLogin adminPrivi = new AdminLogin();
            adminPrivi.ShowDialog();
            if (adminPrivi.isInputPassword)
            {
                string password = ShareData.loginPassword;
                if (adminPrivi.password == password)
                {
                    this.操作员ToolStripMenuItem.Image = null;
                    this.管理员ToolStripMenuItem.Image = Properties.Resources.checkmark;
                    this.ts_SetParaForm.Enabled = true;
                    this.ts_calibration.Enabled = true;
                    this.ts_cameraSet.Enabled = true;
                    this.lab_userName.Text = "用户：管理员";
                }
                else
                {
                    MessageBox.Show("输入密码有误！");
                }
            }
        }
        private void 操作员ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.管理员ToolStripMenuItem.Image = null;
            this.操作员ToolStripMenuItem.Image = Properties.Resources.checkmark;
            this.ts_SetParaForm.Enabled = false;
            this.ts_calibration.Enabled = false;
            this.ts_cameraSet.Enabled = false;
            this.lab_userName.Text = "用户：操作员";
        }

        #endregion

        #region 窗体控件事件

        private void cB_isEmptyRun_CheckedChanged(object sender, EventArgs e)
        {
            if (this.cB_isEmptyRun.Checked)
                isEmptyRun = true;
            else
                isEmptyRun = false;
        }
        private void 清除logToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.lbMsg.Items.Clear();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // SendScanCodeStr("FGH12345ERTYDO89");

            if (threadBusy)
            {
                upCamStatus = WorkStatus.上相机组装2;
                ShareData.MvsCameral.SetHKCamExposure(ProjectInfo.Parameter.upCamIndex, ProjectInfo.Parameter.upCamExposure2);   //设置曝光
                Thread.Sleep(10);
                ShareData.MvsCameral.SoftTriggerOnce(ProjectInfo.Parameter.upCamIndex);          //上相机软触发一次
            }
            else
            {
                MessageBox.Show("相机未初始化,请开始检测！");
            }
        }

        private void cB_Repet_CheckedChanged(object sender, EventArgs e)
        {
            if (cB_Repet.Checked)
            {
                ShareData.isRepet = true;
            }
            else
            {
                ShareData.isRepet = false;
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //if (threadBusy)
            //{
            //    downCamStatus = WorkStatus.下相机组装;
            //    ShareData.MvsCameral.SetHKCamExposure(ProjectInfo.Parameter.downCamIndex, ProjectInfo.Parameter.downCamExposure);   //设置曝光
            //    Thread.Sleep(10);
            //    ShareData.MvsCameral.SoftTriggerOnce(ProjectInfo.Parameter.downCamIndex);          //上相机软触发一次
            //}
            //else
            //{
            //    MessageBox.Show("相机未初始化,请开始检测！");
            //}
            SaveBitmap(codeImage, "Code", this.hWindow_scanCode.HalconWindow);
        }

        bool isFlag = false;
        private void button3_Click(object sender, EventArgs e)
        {
            //SendAndShowPhotoError(3, "error");
            if (threadBusy)
            {
                if (!isFlag)
                {
                    isFlag = true;
                    tfTimer.Enabled = true;
                    tfTimer.Start();
                    button3.Text = "间断触发";

                }
                else
                {
                    isFlag = false;
                    tfTimer.Enabled = false;
                    tfTimer.Stop();
                    button3.Text = "引导触发";
                }
            }
            else
            {
                MessageBox.Show("引导相机未初始化,请开始检测！");
            }
        }

        private void tfTimer_Tick(object sender, EventArgs e)
        {
            detectCamStatus = WorkStatus.机械手引导;
            ShareData.MvsCameral.SetHKCamExposure(ProjectInfo.Parameter.guideCamIndex, ProjectInfo.Parameter.guideCamExposure);   //设置曝光
            Thread.Sleep(20);
            ShareData.MvsCameral.SoftTriggerOnce(ProjectInfo.Parameter.guideCamIndex);          //相机软触发一次            //Invoke(this.dGSetStateShow, "working", Color.Lime);
            SendPhotoDownSignal(4, 1);
        }

        private void button_SendSN_Click(object sender, EventArgs e)
        {
            //string codeStr = "12345678912345-7-";
            // SendScanCodeStr(codeStr);                     //发送码
            ShareData.strSNCode = "";
            ShareData.strSNCode = GetSNcodeFromPLC();
            if (ShareData.strSNCode != null) ShareData.strSNCode = ShareData.strSNCode.Replace("\0", "");
            AddFormLog("手动获取SN: " + ShareData.strSNCode);
            logRecord.WriteLog("手动获取SN: " + ShareData.strSNCode);
        }

        private void btnCode_Click(object sender, EventArgs e)
        {
            string filePath = "";
            OpenFileDialog opg = new OpenFileDialog();
            if (opg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                filePath = opg.FileName;
            }

            if (filePath != "")
            {
                HObject ho_image = null;
                HOperatorSet.GenEmptyObj(out ho_image);
                HOperatorSet.ReadImage(out ho_image, filePath);

                HTuple hv_code = null;
                HTuple hv_result = null;
                halconAlgorithm.FindCode(ho_image, out hv_code, out hv_result);
                if (hv_result == 0)
                {
                    //成功扫到码
                    string codeStr = hv_code.S;
                    SendScanCodeStr(codeStr);                     //发送码
                    AddFormLog("手动扫码成功！" + codeStr);
                    logRecord.WriteLog("手动扫码成功！" + codeStr);
                    this.Invoke(new Action(() =>
                    {
                        this.tB_coilCode.Text = codeStr;
                    }));
                }
                else
                {
                    MessageBox.Show("扫码失败!");
                    logRecord.WriteLog("扫码失败!");
                }
            }
        }

        #endregion

        #region PLC通信函数
        public string plcReadyAddress = "D5052";
        public string judgeProductAddress = "D5015";

        public string noticeRobotAddress = "D5020";  //机械手走位信号
        public string robotAddress = "D5022";       //包含D2022 - D2025，X：2022-2023  Y：= 2024-2025

        public string productCodeAddress = "D5060";
        public string coilCodeAddress = "D5070";
        public bool SendPCReadySignal(int value)
        {
            return ShareData.tcpMitsubishiTCP.WriteInt16(plcReadyAddress, (short)value);
        }
        public string GetSNcodeFromPLC()
        {
            return ShareData.tcpMitsubishiTCP.ReadString(productCodeAddress, 10);
        }
        public bool SendScanCodeStr(string str)
        {
            return ShareData.tcpMitsubishiTCP.WriteString(coilCodeAddress, str);
        }
        public bool RobotGuideJudgeProExist(int index)
        {
            return ShareData.tcpMitsubishiTCP.WriteInt16(judgeProductAddress, (short)index);
        }
        public bool SetRobotGuideCoor(int x, int y)
        {
            int[] values = new int[] { x, y };
            return ShareData.tcpMitsubishiTCP.WriteInt32s(robotAddress, values);
        }
        public bool NoticeRobotGuideMoveSignal(int value)
        {
            //机械手走位信号
            return ShareData.tcpMitsubishiTCP.WriteInt16(noticeRobotAddress, (short)value);
        }

        //2010 - 2014结果信号
        public bool SendPhotoDownSignal(int order, int nflag)
        {
            string plcAddress = "";
            switch (order)
            {
                case 1:
                    plcAddress = "D5010";
                    break;
                case 2:
                    plcAddress = "D5011";
                    break;
                case 3:
                    plcAddress = "D5012";
                    break;
                case 4:
                    plcAddress = "D5013";
                    break;
                case 5:
                    plcAddress = "D5014";
                    break;
                case 6:
                    plcAddress = "D5014";
                    break;
            }
            return ShareData.tcpMitsubishiTCP.WriteInt16(plcAddress, (short)nflag);
        }

        //扫码结果信号，1 成功，2失败
        public bool SendScanCodeResultSignal(int order)
        {
            return ShareData.tcpMitsubishiTCP.WriteInt16("D5042", (short)order);
        }
        //撕模结果信号，1 成功，2失败
        public bool SendSiMoReusltSignal(int order)
        {
            return ShareData.tcpMitsubishiTCP.WriteInt16("D5041", (short)order);
        }

        public bool SendPCErrorSignal(int order)
        {
            //PC异常信号
            return ShareData.tcpMitsubishiTCP.WriteInt16("D5050", (short)order);
        }

        public bool SetAssemblyOffsetCoor(int x, int y, int angle)
        {
            //对位纠偏走位信号
            //2032-2037	2032-2033: X坐标（um）；2034-2035：Y坐标（um）；2036-2037：角度(毫度)
            int[] values = new int[] { x, y, angle };
            return ShareData.tcpMitsubishiTCP.WriteInt32s("D5032", values);
        }

        //AOI检测结果
        public bool SendReviewDetectResult(int result)
        {
            //复检结果信号  D2040
            return ShareData.tcpMitsubishiTCP.WriteInt16("D5040", (short)result);
        }
        public bool NoticeAssemblyMoveSignal(int order)
        {
            //对位纠偏通知走位信号 2030 0/1（0为复位信号，1为走位信号）
            return ShareData.tcpMitsubishiTCP.WriteInt16("D5030", (short)order);
        }

        Thread plcThread = null;
        bool bPlcStop = true;
        public void StartPlc()
        {
            bPlcStop = false;
            plcThread = new Thread(new ThreadStart(StartListen));
            plcThread.IsBackground = true;
            plcThread.Start();
        }
        public void StopPlc()
        {
            bPlcStop = true;
            if (plcThread != null)
            {
                Thread.Sleep(500);
                plcThread = null;
            }
        }

        bool[] bCanPhoto = new bool[] { false, false, false, false, false, false, false, false };
        public void StartListen()
        {
            while (!bPlcStop)
            {
                short[] tmpValues = ShareData.tcpMitsubishiTCP.ReadInt16s("D5000", 8);

                if (tmpValues == null)
                {
                    continue;
                }
                //胶形检测信号
                if (tmpValues[0] == 0)
                {
                    bCanPhoto[0] = true;
                }

                if (tmpValues[0] == 1 && bCanPhoto[0])
                {
                    bCanPhoto[0] = false;

                    this.Invoke(new Action(() =>
                    {
                        ShareData.tcpMitsubishiTCP.WriteInt16("D5000", 0);
                    }));
                    //胶形检测线程开启
                }

                //guide引导相机检测信号
                if (tmpValues[1] == 0)
                {
                    bCanPhoto[1] = true;
                }

                if (tmpValues[1] == 1 && bCanPhoto[1])
                {
                    bCanPhoto[1] = false;

                    //引导相机线程开启
                    Task.Factory.StartNew(
                        () =>
                        {
                            //收到机械手引导信号
                            detectCamStatus = WorkStatus.机械手引导;
                            //if (isEmptyRun)
                            //{
                            //    //空跑模式
                            //    AddFormLog("收到机械手引导信号！");
                            //    logRecord.WriteLog("收到机械手引导信号！");
                            //    Thread.Sleep(100);
                            //     RobotGuideJudgeProExist(1);            //发送有料信号，2代表无料
                            //    Thread.Sleep(50);
                            //     SendPhotoDownSignal(2, 1);             //发送拍照完成信号                       
                            //    Thread.Sleep(50);
                            //     SetRobotGuideCoor(2000, 1500);          //发送机械手引导坐标，单位像素
                            //    Thread.Sleep(50);
                            //     NoticeRobotGuideMoveSignal(1);         //通知机械手走位信号
                            //    AddFormLog("发送机械手引导完成信号");
                            //    logRecord.WriteLog("发送机械手引导完成信号！");
                            //    return;
                            //}
                            Invoke(this.dGSetStateShow, "working", Color.Lime);
                            ShareData.MvsCameral.SetHKCamExposure(ProjectInfo.Parameter.guideCamIndex, ProjectInfo.Parameter.guideCamExposure);   //设置曝光
                            Thread.Sleep(50);
                            ShareData.MvsCameral.SoftTriggerOnce(ProjectInfo.Parameter.guideCamIndex);  //相机软触发一次
                            this.logRecord.WriteLog("收到机械手引导信号1！");
                            AddFormLog("收到机械手引导信号1！");
                        });

                    this.Invoke(new Action(() =>
                    {
                        ShareData.tcpMitsubishiTCP.WriteInt16("D5001", 0);
                    }));
                }

                //上相机 upCamStr
                if (tmpValues[2] == 0)
                {
                    bCanPhoto[2] = true;
                }

                if (tmpValues[2] == 1 && bCanPhoto[2])
                {
                    bCanPhoto[2] = false;

                    Task.Factory.StartNew(() =>
                    {  //收到上相机对位信号，流道1
                        upCamStatus = WorkStatus.上相机组装1;
                        if (isEmptyRun)
                        {
                            //空跑
                            AddFormLog("收到上相机组1装拍照信号1！");
                            logRecord.WriteLog("收到上相机组装1拍照信号1！");
                            Thread.Sleep(100);
                            SendPhotoDownSignal(3, 1);  //发送拍照完成信号
                            AddFormLog("发送上相机组装1拍照完成信号1");
                            logRecord.WriteLog("发送上相机组装1拍照完成信号1！");
                            upCamLocatDown1 = true;
                            return;
                        }
                        detectTime.Reset();
                        detectTime.Start();
                        StartTime = DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss");    //记录开始时间
                        Invoke(this.dGSetStateShow, "working", Color.Lime);
                        ShareData.MvsCameral.SetHKCamExposure(ProjectInfo.Parameter.upCamIndex, ProjectInfo.Parameter.upCamExposure1);   //设置曝光
                        Thread.Sleep(100);
                        ShareData.MvsCameral.SoftTriggerOnce(ProjectInfo.Parameter.upCamIndex);          //上相机软触发一次
                        this.logRecord.WriteLog("收到上相机组装1拍照信号1！");
                        AddFormLog("收到上相机组装1拍照信号1！");
                    });


                    this.Invoke(new Action(() =>
                    {
                        ShareData.tcpMitsubishiTCP.WriteInt16("D5002", 0);
                    }));
                }
                else if (tmpValues[2] == 2 && bCanPhoto[2])
                {
                    bCanPhoto[2] = false;
                    Task.Factory.StartNew(() =>
                    {  //收到上相机对位信号,流道2
                        upCamStatus = WorkStatus.上相机组装2;
                        if (isEmptyRun)
                        {
                            //空跑
                            AddFormLog("收到上相机组装2拍照信号2！");
                            logRecord.WriteLog("收到上相机组装2拍照信号2！");
                            Thread.Sleep(100);
                            SendPhotoDownSignal(3, 1);           //发送拍照完成信号
                            AddFormLog("发送上相机组装2拍照完成信号1");
                            logRecord.WriteLog("发送上相机组装2拍照完成信号1！");
                            upCamLocatDown2 = true;
                            return;
                        }
                        detectTime.Reset();
                        detectTime.Start();
                        StartTime = DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss");    //记录开始时间
                        Invoke(this.dGSetStateShow, "working", Color.Lime);
                        ShareData.MvsCameral.SetHKCamExposure(ProjectInfo.Parameter.upCamIndex, ProjectInfo.Parameter.upCamExposure2);   //设置曝光
                        Thread.Sleep(100);
                        ShareData.MvsCameral.SoftTriggerOnce(ProjectInfo.Parameter.upCamIndex);          //上相机软触发一次
                        this.logRecord.WriteLog("收到上相机组装2拍照信号2！");
                        AddFormLog("收到上相机组装2拍照信号2！");
                    });

                    this.Invoke(new Action(() =>
                    {
                        ShareData.tcpMitsubishiTCP.WriteInt16("D5002", 0);
                    }));

                }

                //下相机引导,包含对位、撕膜
                if (tmpValues[3] == 0)
                {
                    bCanPhoto[3] = true;
                }

                if (tmpValues[3] == 1 && bCanPhoto[3])
                {
                    bCanPhoto[3] = false;

                    Task.Factory.StartNew(() =>
                    {  //收到下相机对位信号
                        downCamStatus = WorkStatus.下相机组装;
                        if (!ShareData.isRepet)
                        {
                            if (isEmptyRun)
                            {
                                //空跑               
                                AddFormLog("收到下相机组装拍照信号！");
                                logRecord.WriteLog("收到下相机组装拍照信号！");
                                Thread.Sleep(100);
                                SendPhotoDownSignal(4, 1);          //发送拍照完成信号                        
                                //Thread.Sleep(50);
                                // SendSiMoReusltSignal(1);            //发送撕膜结果信号收到下相机组装拍照信号！,1为撕膜成功信号
                                AddFormLog("收到下相机组装拍照完成信号!");
                                logRecord.WriteLog("收到下相机组装拍照完成信号！");
                                downCamLocatDown = true;
                                downCamSiMoDown = true;
                                downCamCodeDown = true;

                                AddFormLog("扫码完成信号！");
                                Thread.Sleep(100);
                                SendScanCodeResultSignal(1);
                                logRecord.WriteLog("扫码完成");

                                Thread.Sleep(200);
                                SetAssemblyOffsetCoor((int)(0.1 * 1000), (int)(0.2 * 1000), (int)(0.1 * 1000));    //分别*1000,转化为mm，读数*1000,转为毫度
                                Thread.Sleep(50);                                                                         //延时50ms再发送重置信号
                                NoticeAssemblyMoveSignal(1);

                                //通知plc走位信号   
                                AddFormLog("发送位置补偿信号");
                                logRecord.WriteLog("发送位置补偿信号");
                                return;
                            }
                        }
                        ShareData.MvsCameral.SetHKCamExposure(ProjectInfo.Parameter.downCamIndex, ProjectInfo.Parameter.downCamExposure);   //设置曝光
                        ShareData.MvsCameral.SetHKCamExposure(ProjectInfo.Parameter.downCamIndex, ProjectInfo.Parameter.downCamGamma);      //设置伽马
                        Thread.Sleep(50);
                        ShareData.MvsCameral.SoftTriggerOnce(ProjectInfo.Parameter.downCamIndex);        //下相机软触发一次                            
                        this.logRecord.WriteLog("收到下相机组装拍照信号！");
                        AddFormLog("收到下相机组装拍照信号！");
                    });

                    this.Invoke(new Action(() =>
                    {
                        ShareData.tcpMitsubishiTCP.WriteInt16("D5003", 0);
                    }));
                }
                else if (tmpValues[3] == 2 && bCanPhoto[3])
                {
                    bCanPhoto[3] = false;

                    Task.Factory.StartNew(() =>
                    {  //收到下相机撕膜拍照信号
                        downCamStatus = WorkStatus.撕膜工位;
                        if (isEmptyRun)
                        {
                            AddFormLog("收到下相机撕膜拍照信号！");
                            logRecord.WriteLog("收到下相机撕膜拍照信号！");
                            Thread.Sleep(100);
                            SendPhotoDownSignal(4, 2);          //发送拍照完成信号   
                            Thread.Sleep(150);
                            SendSiMoReusltSignal(1);            //发送撕膜结果信号,1为撕膜成功信号，2为失败信号
                            AddFormLog("发送下相机撕膜拍照完成信号！");
                            logRecord.WriteLog("发送下相机撕膜拍照完成信号！");
                            return;
                        }
                        ShareData.MvsCameral.SetHKCamExposure(ProjectInfo.Parameter.downCamIndex, ProjectInfo.Parameter.simoCamExposure);   //设置曝光
                        ShareData.MvsCameral.SetHKCamExposure(ProjectInfo.Parameter.downCamIndex, ProjectInfo.Parameter.simoCamGamma);   //设置曝光
                        Thread.Sleep(10);
                        ShareData.MvsCameral.SoftTriggerOnce(ProjectInfo.Parameter.downCamIndex);        //下相机软触发一次                            
                        this.logRecord.WriteLog("发送下相机撕膜拍照完成信号！");
                        AddFormLog("发送下相机撕膜拍照完成信号！");
                    });

                    this.Invoke(new Action(() =>
                    {
                        ShareData.tcpMitsubishiTCP.WriteInt16("D5003", 0);
                    }));
                }

                if (tmpValues[4] == 0)
                {
                    bCanPhoto[4] = true;
                }

                if (tmpValues[4] == 1 && bCanPhoto[4])
                {
                    bCanPhoto[4] = false;
                    this.Invoke(new Action(() =>
                    {
                        ShareData.tcpMitsubishiTCP.WriteInt16("D5004", 0);
                    }));
                    //自检拍照线程
                }

                if (tmpValues[7] == 0)
                {
                    bCanPhoto[7] = true;
                }

                if (tmpValues[7] == 1 && bCanPhoto[7])
                {
                    bCanPhoto[7] = false;

                    Task.Factory.StartNew(() =>
                    {    //收到PLC复位信号
                        downCamLocatDown = false;
                        downCamSiMoDown = false;
                        downCamCodeDown = false;

                        angleRegulateNum = 0;
                        while (!channelQueue.IsEmpty)   //清空队列
                        {
                            int mChannel = -1;
                            channelQueue.TryDequeue(out mChannel);
                        }

                        Thread.Sleep(500);
                        ShareData.tcpMitsubishiTCP.WriteInt16("D5007", 0);


                        this.logRecord.WriteLog("复位信号完成！");
                        AddFormLog("PLC复位信号完成！");
                    });


                }
                Thread.Sleep(50);
            }
        }
        #endregion

    }
}
